From 638661187189040ccbcd3a5afa7838a9ab8eed28 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 30 Mar 2011 15:15:15 +0200 Subject: [PATCH 01/29] Let the testing begin --- src/sip/jreen/jabber_p.cpp | 42 ++++++++++++++++++++++++++++++++++++-- src/sip/jreen/jabber_p.h | 5 ++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 93987b35e..ab099e937 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -76,6 +76,8 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message))); connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence))); + + qDebug() << "DISCOFEATURES:" << m_client->disco()->features(); qDebug() << "Connecting to the XMPP server..."; m_client->connectToServer(); } @@ -193,7 +195,14 @@ Jabber_p::onConnect() m_client->setPresence(Jreen::Presence::Available, "Tomahawk-JREEN available", 1); m_client->disco()->setSoftwareVersion( "Tomahawk JREEN", "0.0.0.0", "Foobar" ); + + m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) ); + + m_client->disco()->addFeature( "tomahawk" ); + + qDebug() << "DISCOFEATURES connected:" << m_client->disco()->features(); m_client->setPingInterval(60000); + m_roster = new Jreen::SimpleRoster( m_client ); m_roster->load(); @@ -291,6 +300,16 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) qDebug() << Q_FUNC_INFO << "handle presence" << fulljid << presence.subtype(); + Jreen::IQ iq(Jreen::IQ::Get,jid); + + Jreen::Capabilities::Ptr caps = presence.findExtension(); + if(caps) + { + QString node = caps->node() + '#' + caps->ver(); + iq.addExtension(new Jreen::Disco::Info(node)); + m_client->send(iq,this,SLOT(onIQ(Jreen::IQ,int)),RequestDisco); + } + if( jid == m_jid ) return; @@ -300,7 +319,7 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) } // ignore anyone not running tomahawk: - Jreen::Capabilities::Ptr caps = presence.findExtension(); + //Jreen::Capabilities::Ptr caps = presence.findExtension(); if ( caps && (caps->node() == TOMAHAWK_CAP_NODE_NAME )) { qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk detected by caps"; @@ -355,6 +374,25 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) } +void +Jabber_p::onIQ( const Jreen::IQ &iq, int context ) +{ + if(context == RequestDisco) { + Jreen::Disco::Info *discoInfo = iq.findExtension().data(); + if(!discoInfo) + return; + iq.accept(); + + + QString jid = iq.from().full(); + Jreen::DataForm::Ptr form = discoInfo->form(); + + qDebug() << jid << "NODE" << discoInfo->node(); + qDebug() << "jid:" << jid << "FEATURES" << discoInfo->features(); + qDebug() << jid << "DATA" << form; + } +} + bool Jabber_p::presenceMeansOnline( Jreen::Presence::Type p ) { diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index ab0826f20..2a62551d5 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -87,6 +87,7 @@ private slots: { qDebug() << e; } + virtual void onIQ( const Jreen::IQ &iq, int context ); private: bool presenceMeansOnline( Jreen::Presence::Type p ); @@ -97,6 +98,8 @@ private: QMap m_presences; QMap m_peers; QString m_server; + + enum m_iqContext { RequestDisco }; }; #endif // JABBER_H From ff0d5613bb14e945b27a66ffe78e25e9b0912393 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 30 Mar 2011 15:52:49 +0200 Subject: [PATCH 02/29] Set features at the right time --- src/sip/jreen/jabber_p.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index ab099e937..1ea816df3 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -60,6 +60,10 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& m_jid = Jreen::JID( jid ); m_client = new Jreen::Client( jid, password ); + m_client->disco()->setSoftwareVersion( "Tomahawk JREEN", "0.0.0.0", "Foobar" ); + + m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) ); + m_client->disco()->addFeature( "tomahawk" ); m_client->setResource( QString( "tomahawk%1" ).arg( "DOMME" ) ); Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); @@ -194,11 +198,6 @@ Jabber_p::onConnect() qDebug() << "Connected as:" << m_jid.full(); m_client->setPresence(Jreen::Presence::Available, "Tomahawk-JREEN available", 1); - m_client->disco()->setSoftwareVersion( "Tomahawk JREEN", "0.0.0.0", "Foobar" ); - - m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) ); - - m_client->disco()->addFeature( "tomahawk" ); qDebug() << "DISCOFEATURES connected:" << m_client->disco()->features(); m_client->setPingInterval(60000); From 63d7fc0b38dd4412cd488004ffa21b02aac63f13 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 4 Apr 2011 16:44:39 +0200 Subject: [PATCH 03/29] Do some cleanup and add comments in jreen sip plugin --- CMakeLists.txt | 8 +- src/config.h.in | 9 +- src/sip/jreen/CMakeLists.txt | 6 +- src/sip/jreen/jabber.cpp | 3 +- src/sip/jreen/jabber.h | 5 +- src/sip/jreen/jabber_p.cpp | 196 +++++++++++++---------------------- src/sip/jreen/jabber_p.h | 32 +++--- src/tomahawkapp.cpp | 32 +++--- 8 files changed, 119 insertions(+), 172 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f848d45ed..a19ec507c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,10 @@ CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) ### ### Tomahawk application info ### -SET( ORGANIZATION_NAME "Tomahawk" ) -SET( ORGANIZATION_DOMAIN "tomahawk-player.org" ) -SET( APPLICATION_NAME "Tomahawk" ) -SET( VERSION "0.0.2" ) +SET( TOMAHAWK_ORGANIZATION_NAME "Tomahawk" ) +SET( TOMAHAWK_ORGANIZATION_DOMAIN "tomahawk-player.org" ) +SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" ) +SET( TOMAHAWK_VERSION "0.0.2" ) # set paths diff --git a/src/config.h.in b/src/config.h.in index f8246a54d..7ac3931a2 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -1,14 +1,15 @@ #ifndef CONFIG_H_IN #define CONFIG_H_IN -#cmakedefine ORGANIZATION_NAME "${ORGANIZATION_NAME}" -#cmakedefine ORGANIZATION_DOMAIN "${ORGANIZATION_DOMAIN}" -#cmakedefine APPLICATION_NAME "${APPLICATION_NAME}" -#cmakedefine VERSION "${VERSION}" +#cmakedefine TOMAHAWK_ORGANIZATION_NAME "${TOMAHAWK_ORGANIZATION_NAME}" +#cmakedefine TOMAHAWK_ORGANIZATION_DOMAIN "${TOMAHAWK_ORGANIZATION_DOMAIN}" +#cmakedefine TOMAHAWK_APPLICATION_NAME "${TOMAHAWK_APPLICATION_NAME}" +#cmakedefine TOMAHAWK_VERSION "${TOMAHAWK_VERSION}" #cmakedefine DEBUG_BUILD #define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" +#define CMAKE_SYSTEM "${CMAKE_SYSTEM}" #cmakedefine SNOW_LEOPARD #cmakedefine LEOPARD diff --git a/src/sip/jreen/CMakeLists.txt b/src/sip/jreen/CMakeLists.txt index df2a4f7b6..31895f2fc 100644 --- a/src/sip/jreen/CMakeLists.txt +++ b/src/sip/jreen/CMakeLists.txt @@ -22,7 +22,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ) qt4_wrap_cpp( jabberMoc ${jabberHeaders} ) -add_library( tomahawk_sipjreen SHARED ${jabberSources} ${jabberMoc} ) +add_library( tomahawk_sipjabber SHARED ${jabberSources} ${jabberMoc} ) IF( WIN32 ) SET( OS_SPECIFIC_LINK_LIBRARIES @@ -33,7 +33,7 @@ SET( OS_SPECIFIC_LINK_LIBRARIES ) ENDIF( WIN32 ) -target_link_libraries( tomahawk_sipjreen +target_link_libraries( tomahawk_sipjabber ${QT_LIBRARIES} ${LIBJREEN_LIBRARY} ${OS_SPECIFIC_LINK_LIBRARIES} @@ -43,4 +43,4 @@ IF( APPLE ) # SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) ENDIF( APPLE ) -install( TARGETS tomahawk_sipjreen DESTINATION lib${LIB_SUFFIX} ) +install( TARGETS tomahawk_sipjabber DESTINATION lib${LIB_SUFFIX} ) diff --git a/src/sip/jreen/jabber.cpp b/src/sip/jreen/jabber.cpp index c97067f59..2c40bbb5f 100644 --- a/src/sip/jreen/jabber.cpp +++ b/src/sip/jreen/jabber.cpp @@ -1,5 +1,6 @@ /* === This file is part of Tomahawk Player - === - * + * + * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify diff --git a/src/sip/jreen/jabber.h b/src/sip/jreen/jabber.h index ccbbafc0e..080ff78c3 100644 --- a/src/sip/jreen/jabber.h +++ b/src/sip/jreen/jabber.h @@ -1,5 +1,6 @@ /* === This file is part of Tomahawk Player - === - * + * + * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -24,7 +25,7 @@ #include "../sipdllmacro.h" -#define MYNAME "SIPJABBER" +#define MYNAME "SIPJREEN" class SIPDLLEXPORT JabberPlugin : public SipPlugin { diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 1ea816df3..5367bfab4 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -1,5 +1,6 @@ /* === This file is part of Tomahawk Player - === * + * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -18,21 +19,16 @@ #include "jabber_p.h" +#include "config.h" +#include "utils/tomahawkutils.h" + #include #include #include #include #include #include -#include -#include -#include - - -//remove -#include -#include using namespace std; @@ -44,35 +40,30 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& , m_server() { qDebug() << Q_FUNC_INFO; - //qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) ); qsrand(QDateTime::currentDateTime().toTime_t()); - m_presences[Jreen::Presence::Available] = "available"; - m_presences[Jreen::Presence::Chat] = "chat"; - m_presences[Jreen::Presence::Away] = "away"; - m_presences[Jreen::Presence::DND] = "dnd"; - m_presences[Jreen::Presence::XA] = "xa"; - m_presences[Jreen::Presence::Unavailable] = "unavailable"; - m_presences[Jreen::Presence::Probe] = "probe"; - m_presences[Jreen::Presence::Error] = "error"; - m_presences[Jreen::Presence::Invalid] = "invalid"; - + // setup JID object m_jid = Jreen::JID( jid ); + // general client setup m_client = new Jreen::Client( jid, password ); - m_client->disco()->setSoftwareVersion( "Tomahawk JREEN", "0.0.0.0", "Foobar" ); + m_client->setResource( QString( "tomahawk%1" ).arg( qrand() ) ); + // setup disco + m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM ); m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) ); - m_client->disco()->addFeature( "tomahawk" ); - m_client->setResource( QString( "tomahawk%1" ).arg( "DOMME" ) ); + m_client->disco()->addFeature( "tomahawk:sip:v1" ); + // setup caps node, legacy peer detection - used before 0.1 Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); caps->setNode(TOMAHAWK_CAP_NODE_NAME); + // print connection parameters qDebug() << "Our JID set to:" << m_client->jid().full(); qDebug() << "Our Server set to:" << m_client->server(); qDebug() << "Our Port set to" << m_client->port(); + // setup slots connect(m_client->connection(), SIGNAL(error(SocketError)), SLOT(onError(SocketError))); connect(m_client, SIGNAL(serverFeaturesReceived(QSet)), SLOT(onConnect())); connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)), SLOT(onDisconnect(Jreen::Client::DisconnectReason))); @@ -81,7 +72,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence))); - qDebug() << "DISCOFEATURES:" << m_client->disco()->features(); + // connect qDebug() << "Connecting to the XMPP server..."; m_client->connectToServer(); } @@ -112,18 +103,6 @@ void Jabber_p::sendMsg( const QString& to, const QString& msg ) { qDebug() << Q_FUNC_INFO; - if ( QThread::currentThread() != thread() ) - { - qDebug() << Q_FUNC_INFO << "invoking in correct thread, not" - << QThread::currentThread(); - - QMetaObject::invokeMethod( this, "sendMsg", - Qt::QueuedConnection, - Q_ARG( const QString, to ), - Q_ARG( const QString, msg ) - ); - return; - } if ( !m_client ) { return; @@ -132,7 +111,7 @@ Jabber_p::sendMsg( const QString& to, const QString& msg ) qDebug() << Q_FUNC_INFO << to << msg; Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg); - m_client->send( m ); // assuming this is threadsafe + m_client->send( m ); } @@ -140,14 +119,6 @@ void Jabber_p::broadcastMsg( const QString &msg ) { qDebug() << Q_FUNC_INFO; - if ( QThread::currentThread() != thread() ) - { - QMetaObject::invokeMethod( this, "broadcastMsg", - Qt::QueuedConnection, - Q_ARG(const QString, msg) - ); - return; - } if ( !m_client ) return; @@ -155,7 +126,7 @@ Jabber_p::broadcastMsg( const QString &msg ) foreach( const QString& jidstr, m_peers.keys() ) { qDebug() << "Broadcasting to" << jidstr <<"..."; - Jreen::Message m(Jreen::Message::Chat, Jreen::JID(jidstr), msg, ""); + Jreen::Message m( Jreen::Message::Chat, Jreen::JID(jidstr), msg, "" ); m_client->send( m ); } } @@ -164,16 +135,6 @@ Jabber_p::broadcastMsg( const QString &msg ) void Jabber_p::addContact( const QString& jid, const QString& msg ) { - if ( QThread::currentThread() != thread() ) - { - QMetaObject::invokeMethod( this, "addContact", - Qt::QueuedConnection, - Q_ARG(const QString, jid), - Q_ARG(const QString, msg) - ); - return; - } - // Add contact to the Tomahawk group on the roster m_roster->add( jid, jid, QStringList() << "Tomahawk" ); @@ -189,6 +150,7 @@ Jabber_p::onConnect() // have changed our requested /resource if ( m_client->jid().resource() != m_jid.resource() ) { + // TODO: check if this is still neccessary with jreen m_jid.setResource( m_client->jid().resource() ); QString jidstr( m_jid.full() ); emit jidChanged( jidstr ); @@ -197,18 +159,21 @@ Jabber_p::onConnect() emit connected(); qDebug() << "Connected as:" << m_jid.full(); - m_client->setPresence(Jreen::Presence::Available, "Tomahawk-JREEN available", 1); + // set presence to least valid value + m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127); - qDebug() << "DISCOFEATURES connected:" << m_client->disco()->features(); - m_client->setPingInterval(60000); + // set ping timeout to 15 secs (TODO: verify if this works) + m_client->setPingInterval(15000); + // load roster m_roster = new Jreen::SimpleRoster( m_client ); m_roster->load(); + //FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P // join MUC with bare jid as nickname //TODO: make the room a list of rooms and make that configurable - QString bare(m_jid.bare()); - m_room = new Jreen::MUCRoom(m_client, Jreen::JID(QString("tomahawk@conference.qutim.org/").append(bare.replace("@", "-")))); + QString mucNickname = QString( "tomahawk@conference.qutim.org/" ).append( QString( m_jid.bare() ).replace( "@", "-" ) ); + m_room = new Jreen::MUCRoom(m_client, Jreen::JID( mucNickname ) ); //m_room->setHistorySeconds(0); //m_room->join(); @@ -286,110 +251,59 @@ Jabber_p::onNewMessage( const Jreen::Message& m ) if ( msg.isEmpty() ) return; - qDebug() << Q_FUNC_INFO << m.from().full() << ":" << m.body(); + qDebug() << Q_FUNC_INFO << "From:" << m.from().full() << ":" << m.body(); emit msgReceived( from, msg ); } void Jabber_p::onNewPresence( const Jreen::Presence& presence) { - Jreen::JID jid = presence.from(); QString fulljid( jid.full() ); - qDebug() << Q_FUNC_INFO << "handle presence" << fulljid << presence.subtype(); - - Jreen::IQ iq(Jreen::IQ::Get,jid); - - Jreen::Capabilities::Ptr caps = presence.findExtension(); - if(caps) - { - QString node = caps->node() + '#' + caps->ver(); - iq.addExtension(new Jreen::Disco::Info(node)); - m_client->send(iq,this,SLOT(onIQ(Jreen::IQ,int)),RequestDisco); - } + qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype(); if( jid == m_jid ) return; if ( presence.error() ) { - qDebug() << Q_FUNC_INFO << "presence error: no tomahawk"; + qDebug() << Q_FUNC_INFO << "tomahawk: no" << "presence error"; return; } // ignore anyone not running tomahawk: - //Jreen::Capabilities::Ptr caps = presence.findExtension(); + Jreen::Capabilities::Ptr caps = presence.findExtension(); if ( caps && (caps->node() == TOMAHAWK_CAP_NODE_NAME )) { - qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk detected by caps"; + qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk: yes" << "caps " << caps->node(); } - // this is a hack actually as long as gloox based libsip_jabber is around - // remove this as soon as everyone is using jreen else if( presence.from().resource().startsWith( QLatin1String("tomahawk") ) ) { - qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk detected by resource"; + // this is a hack actually as long as gloox based libsip_jabber is around + // remove this as soon as everyone is using jreen + // supported by gloox too - should be removed + qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk: yes" << "resource"; } else if( caps && caps->node() != TOMAHAWK_CAP_NODE_NAME ) { - qDebug() << Q_FUNC_INFO << presence.from().full() << "*no tomahawk* detected by caps!" << caps->node() << presence.from().resource(); + qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk: no" << "caps" << caps->node(); return; } else if( !caps ) { - qDebug() << Q_FUNC_INFO << "no tomahawk detected by resource and !caps"; + qDebug() << Q_FUNC_INFO << "tomahawk: no" << "no indication"; return; } qDebug() << Q_FUNC_INFO << fulljid << " is a tomahawk resource."; - // "going offline" event - if ( !presenceMeansOnline( presence.subtype() ) && - ( !m_peers.contains( fulljid ) || - presenceMeansOnline( m_peers.value( fulljid ) ) - ) - ) - { - m_peers[ fulljid ] = presence.subtype(); - qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid; - emit peerOffline( fulljid ); - return; - } - - // "coming online" event - if( presenceMeansOnline( presence.subtype() ) && - ( !m_peers.contains( fulljid ) || - !presenceMeansOnline( m_peers.value( fulljid ) ) - ) - ) - { - m_peers[ fulljid ] = presence.subtype(); - qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid; - emit peerOnline( fulljid ); - return; - } - - //qDebug() << "Updating presence data for" << fulljid; - m_peers[ fulljid ] = presence.subtype(); - + handlePeerStatus( fulljid, presence.subtype() ); } void -Jabber_p::onIQ( const Jreen::IQ &iq, int context ) +Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) { - if(context == RequestDisco) { - Jreen::Disco::Info *discoInfo = iq.findExtension().data(); - if(!discoInfo) - return; - iq.accept(); - - QString jid = iq.from().full(); - Jreen::DataForm::Ptr form = discoInfo->form(); - - qDebug() << jid << "NODE" << discoInfo->node(); - qDebug() << "jid:" << jid << "FEATURES" << discoInfo->features(); - qDebug() << jid << "DATA" << form; - } } bool @@ -406,3 +320,37 @@ Jabber_p::presenceMeansOnline( Jreen::Presence::Type p ) return true; } } + +void +Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presenceType ) +{ + // "going offline" event + if ( !presenceMeansOnline( presenceType ) && + ( !m_peers.contains( fulljid ) || + presenceMeansOnline( m_peers.value( fulljid ) ) + ) + ) + { + m_peers[ fulljid ] = presenceType; + qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid; + emit peerOffline( fulljid ); + return; + } + + // "coming online" event + if( presenceMeansOnline( presenceType ) && + ( !m_peers.contains( fulljid ) || + !presenceMeansOnline( m_peers.value( fulljid ) ) + ) + ) + { + m_peers[ fulljid ] = presenceType; + qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid; + emit peerOnline( fulljid ); + return; + } + + //qDebug() << "Updating presence data for" << fulljid; + m_peers[ fulljid ] = presenceType; +} + diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index 2a62551d5..081342a6d 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -1,5 +1,6 @@ /* === This file is part of Tomahawk Player - === * + * Copyright 2010-2011, Dominik Schmidt * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -16,20 +17,10 @@ * along with Tomahawk. If not, see . */ -/* - This is the Jabber client that the rest of the app sees - Gloox stuff should NOT leak outside this class. - We may replace jreen later, this interface should remain the same. -*/ #ifndef JABBER_P_H #define JABBER_P_H -#include -#include -#include -#include - -#include +#include "../sipdllmacro.h" #include #include @@ -41,16 +32,19 @@ #include #include #include +#include +#include + +#include +#include +#include +#include #if defined( WIN32 ) || defined( _WIN32 ) -# include +#include #endif -#include "../sipdllmacro.h" -#include -#include - class SIPDLLEXPORT Jabber_p : public QObject { @@ -87,10 +81,12 @@ private slots: { qDebug() << e; } - virtual void onIQ( const Jreen::IQ &iq, int context ); + virtual void onNewIq( const Jreen::IQ &iq, int context ); private: bool presenceMeansOnline( Jreen::Presence::Type p ); + void handlePeerStatus( const QString &fulljid, Jreen::Presence::Type presenceType ); + Jreen::Client *m_client; Jreen::MUCRoom *m_room; Jreen::SimpleRoster *m_roster; @@ -99,7 +95,7 @@ private: QMap m_peers; QString m_server; - enum m_iqContext { RequestDisco }; + enum IqContext { RequestDisco }; }; #endif // JABBER_H diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 46c002c4a..cc76a919d 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -151,15 +151,15 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) , m_infoSystem( 0 ) { qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) ); - + // send the first arg to an already running instance, but don't open twice no matter what if( ( argc > 1 && sendMessage( argv[ 1 ] ) ) || sendMessage( "" ) ) { qDebug() << "Sent message, already exists"; throw runtime_error( "Already Running" ); } - + connect( this, SIGNAL( messageReceived( QString ) ), this, SLOT( messageReceived( QString ) ) ); - + #ifdef TOMAHAWK_HEADLESS m_headless = true; #else @@ -169,18 +169,18 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) #endif qDebug() << "TomahawkApp thread:" << this->thread(); - setOrganizationName( QLatin1String( ORGANIZATION_NAME ) ); - setOrganizationDomain( QLatin1String( ORGANIZATION_DOMAIN ) ); - setApplicationName( QLatin1String( APPLICATION_NAME ) ); - setApplicationVersion( QLatin1String( VERSION ) ); + setOrganizationName( QLatin1String( TOMAHAWK_ORGANIZATION_NAME ) ); + setOrganizationDomain( QLatin1String( TOMAHAWK_ORGANIZATION_DOMAIN ) ); + setApplicationName( QLatin1String( TOMAHAWK_APPLICATION_NAME ) ); + setApplicationVersion( QLatin1String( TOMAHAWK_VERSION ) ); registerMetaTypes(); setupLogfile(); - + new TomahawkSettings( this ); m_audioEngine = new AudioEngine; new ScanManager( this ); new Pipeline( this ); - + m_servent = new Servent( this ); connect( m_servent, SIGNAL( ready() ), SLOT( setupSIP() ) ); @@ -189,7 +189,7 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) qDebug() << "Init Echonest Factory."; GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); - + m_scrubFriendlyName = arguments().contains( "--demo" ); // Register shortcut handler for this platform #ifdef Q_WS_MAC @@ -252,10 +252,10 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) else TomahawkUtils::setProxy( new QNetworkProxy( QNetworkProxy::NoProxy ) ); - + Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" ); Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() ); - + QNetworkProxy::setApplicationProxy( *TomahawkUtils::proxy() ); qDebug() << "Init SIP system."; @@ -343,7 +343,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QMap >("QMap"); qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >"); qRegisterMetaType< QHash< QString, QMap > >("QHash< QString, QMap >"); - + qRegisterMetaType< GeneratorMode>("GeneratorMode"); qRegisterMetaType("Tomahawk::GeneratorMode"); // Extra definition for namespaced-versions of signals/slots required @@ -534,14 +534,14 @@ TomahawkApp::loadUrl( const QString& url ) } -void -TomahawkApp::messageReceived( const QString& msg ) +void +TomahawkApp::messageReceived( const QString& msg ) { qDebug() << "MESSAGE RECEIVED" << msg; if( msg.isEmpty() ) { return; } - + loadUrl( msg ); } From e7ddedef5a3ee66f549a00494122cd4cc84862da Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 4 Apr 2011 20:31:06 +0200 Subject: [PATCH 04/29] Test it, baby! --- src/sip/jreen/CMakeLists.txt | 5 ++ src/sip/jreen/jabber_p.cpp | 162 ++++++++++++++++++++++++++++------- src/sip/jreen/jabber_p.h | 4 +- 3 files changed, 138 insertions(+), 33 deletions(-) diff --git a/src/sip/jreen/CMakeLists.txt b/src/sip/jreen/CMakeLists.txt index 31895f2fc..7cf3d3dd2 100644 --- a/src/sip/jreen/CMakeLists.txt +++ b/src/sip/jreen/CMakeLists.txt @@ -9,11 +9,15 @@ add_definitions( -DSIPDLLEXPORT_PRO ) set( jabberSources jabber.cpp jabber_p.cpp + tomahawksipmessage.cpp + tomahawksipmessagefactory.cpp ) set( jabberHeaders jabber.h jabber_p.h + tomahawksipmessage.h + tomahawksipmessagefactory.h ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. @@ -37,6 +41,7 @@ target_link_libraries( tomahawk_sipjabber ${QT_LIBRARIES} ${LIBJREEN_LIBRARY} ${OS_SPECIFIC_LINK_LIBRARIES} + tomahawklib ) IF( APPLE ) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 5367bfab4..50e103c35 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -18,22 +18,28 @@ */ #include "jabber_p.h" +#include "tomahawksipmessage.h" #include "config.h" #include "utils/tomahawkutils.h" +#include + +#include +#include + #include #include #include #include #include #include +#include +#include +#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" ) -using namespace std; - - -#define TOMAHAWK_CAP_NODE_NAME QLatin1String("http://tomahawk-player.org/") +#define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" ) Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& server, const int port ) : QObject() @@ -47,16 +53,17 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& // general client setup m_client = new Jreen::Client( jid, password ); - m_client->setResource( QString( "tomahawk%1" ).arg( qrand() ) ); + m_client->setResource( QString( "DISABLEDtomahawk%1" ).arg( qrand() ) ); // setup disco m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM ); m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) ); - m_client->disco()->addFeature( "tomahawk:sip:v1" ); + m_client->disco()->addFeature( TOMAHAWK_FEATURE ); // setup caps node, legacy peer detection - used before 0.1 - Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); - caps->setNode(TOMAHAWK_CAP_NODE_NAME); + // disable it for testing + //Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); + //caps->setNode(TOMAHAWK_CAP_NODE_NAME); // print connection parameters qDebug() << "Our JID set to:" << m_client->jid().full(); @@ -108,10 +115,41 @@ Jabber_p::sendMsg( const QString& to, const QString& msg ) return; } - qDebug() << Q_FUNC_INFO << to << msg; - Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg); + /******************************************************* + * Obsolete this by a SipMessage class + */ + QJson::Parser parser; + bool ok; + QVariant v = parser.parse( msg.toAscii(), &ok ); + if ( !ok || v.type() != QVariant::Map ) + { + qDebug() << "Invalid JSON in XMPP msg"; + return; + } + QVariantMap m = v.toMap(); + /*******************************************************/ - m_client->send( m ); + TomahawkSipMessage *sipMessage; + if(m["visible"].toBool()) + { + sipMessage = new TomahawkSipMessage(m["ip"].toString(), + m["port"].toInt(), + m["uniqname"].toString(), + m["key"].toString(), + m["visible"].toBool() + ); + } + else + { + sipMessage = new TomahawkSipMessage(); + } + + + qDebug() << "Send sip messsage to " << to; + Jreen::IQ iq( Jreen::IQ::Set, to ); + iq.addExtension( sipMessage ); + + m_client->send( iq, this, SLOT( onNewIQ( Jreen::IQ, int ) ), SipMessageSent ); } @@ -267,43 +305,105 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) return; if ( presence.error() ) { - qDebug() << Q_FUNC_INFO << "tomahawk: no" << "presence error"; + qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error"; return; } - // ignore anyone not running tomahawk: + // ignore anyone not Running tomahawk: Jreen::Capabilities::Ptr caps = presence.findExtension(); - if ( caps && (caps->node() == TOMAHAWK_CAP_NODE_NAME )) + if ( caps && (caps->node() == TOMAHAWK_CAP_NODE_NAME ) && false) // disable this method to test the new one { - qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk: yes" << "caps " << caps->node(); + // legacy peer detection + qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node(); + handlePeerStatus( fulljid, presence.subtype() ); } - else if( presence.from().resource().startsWith( QLatin1String("tomahawk") ) ) + else if( caps ) { - // this is a hack actually as long as gloox based libsip_jabber is around - // remove this as soon as everyone is using jreen - // supported by gloox too - should be removed - qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk: yes" << "resource"; - } - else if( caps && caps->node() != TOMAHAWK_CAP_NODE_NAME ) - { - qDebug() << Q_FUNC_INFO << presence.from().full() << "tomahawk: no" << "caps" << caps->node(); - return; + qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node() + << "requesting disco.."; + + // request disco features + QString node = caps->node() + '#' + caps->ver(); + + Jreen::IQ iq( Jreen::IQ::Get, jid ); + iq.addExtension( new Jreen::Disco::Info( node ) ); + + m_client->send( iq, this, SLOT( onNewIQ( Jreen::IQ, int ) ), RequestDisco ); } else if( !caps ) { - qDebug() << Q_FUNC_INFO << "tomahawk: no" << "no indication"; - return; + qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps"; } - - qDebug() << Q_FUNC_INFO << fulljid << " is a tomahawk resource."; - - handlePeerStatus( fulljid, presence.subtype() ); } void Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) { + if( context == RequestDisco ) + { + qDebug() << Q_FUNC_INFO << "Received disco IQ..."; + Jreen::Disco::Info *discoInfo = iq.findExtension().data(); + if(!discoInfo) + return; + iq.accept(); + QString fulljid = iq.from().full(); + Jreen::DataForm::Ptr form = discoInfo->form(); + + if(discoInfo->features().contains( TOMAHAWK_FEATURE )) + { + qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: yes"; + + // the actual presence doesn't matter, it just needs to be "online" + handlePeerStatus( fulljid, Jreen::Presence::Available ); + } + else + { + qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: no"; + } + } + else if(context == RequestedDisco) + { + qDebug() << "Sent IQ(Set), what should be happening here?"; + } + else + { + TomahawkSipMessage *sipMessage = iq.findExtension().data(); + if(sipMessage) + { + + qDebug() << Q_FUNC_INFO << "Got SipMessage ..."; + qDebug() << "ip" << sipMessage->ip(); + qDebug() << "port" << sipMessage->port(); + qDebug() << "uniqname" << sipMessage->uniqname(); + qDebug() << "key" << sipMessage->key(); + qDebug() << "visible" << sipMessage->visible(); + + + QVariantMap m; + if( sipMessage->visible() ) + { + m["visible"] = true; + m["ip"] = sipMessage->ip(); + m["port"] = sipMessage->port(); + m["key"] = sipMessage->key(); + m["uniqname"] = sipMessage->uniqname(); + } + else + { + m["visible"] = false; + } + + + QJson::Serializer ser; + QByteArray ba = ser.serialize( m ); + QString msg = QString::fromAscii( ba ); + + QString from = iq.from().full(); + qDebug() << Q_FUNC_INFO << "From:" << from << ":" << msg; + emit msgReceived( from, msg ); + } + } } bool diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index 081342a6d..be5edeeb8 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -81,7 +81,7 @@ private slots: { qDebug() << e; } - virtual void onNewIq( const Jreen::IQ &iq, int context ); + virtual void onNewIq( const Jreen::IQ &iq, int context = NoContext ); private: bool presenceMeansOnline( Jreen::Presence::Type p ); @@ -95,7 +95,7 @@ private: QMap m_peers; QString m_server; - enum IqContext { RequestDisco }; + enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent }; }; #endif // JABBER_H From 16eb50e02da824764ba55ae36ddd6c5a9c0ff1d2 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 4 Apr 2011 20:46:21 +0200 Subject: [PATCH 05/29] Forgot to add tomahawksipmessage stanza extension files --- src/sip/jreen/tomahawksipmessage.cpp | 74 ++++++++++++ src/sip/jreen/tomahawksipmessage.h | 28 +++++ src/sip/jreen/tomahawksipmessagefactory.cpp | 124 ++++++++++++++++++++ src/sip/jreen/tomahawksipmessagefactory.h | 46 ++++++++ 4 files changed, 272 insertions(+) create mode 100644 src/sip/jreen/tomahawksipmessage.cpp create mode 100644 src/sip/jreen/tomahawksipmessage.h create mode 100644 src/sip/jreen/tomahawksipmessagefactory.cpp create mode 100644 src/sip/jreen/tomahawksipmessagefactory.h diff --git a/src/sip/jreen/tomahawksipmessage.cpp b/src/sip/jreen/tomahawksipmessage.cpp new file mode 100644 index 000000000..0dce37b0b --- /dev/null +++ b/src/sip/jreen/tomahawksipmessage.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** + * + * This file is part of qutIM + * + * Copyright (c) 2011 by Nigmatullin Ruslan + * + *************************************************************************** + * * + * This file is part of 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 2 of the * + * License, or (at your option) any later version. * + * * + *************************************************************************** + ****************************************************************************/ + +#include "tomahawksipmessage.h" + +class TomahawkSipMessagePrivate +{ +public: + QString ip; + int port; + QString uniqname; + QString key; + bool visible; +}; + +TomahawkSipMessage::TomahawkSipMessage(QString ip, unsigned int port, QString uniqname, QString key, bool visible) : d_ptr(new TomahawkSipMessagePrivate) +{ + Q_D(TomahawkSipMessage); + d->ip = ip; + d->port = port; + d->uniqname = uniqname; + d->key = key; + d->visible = visible; +} + +TomahawkSipMessage::TomahawkSipMessage() : d_ptr(new TomahawkSipMessagePrivate) +{ + Q_D(TomahawkSipMessage); + d->visible = false; + d->port = -1; +} + + +TomahawkSipMessage::~TomahawkSipMessage() +{ +} + +const QString TomahawkSipMessage::ip() const +{ + return d_func()->ip; +} + +unsigned int TomahawkSipMessage::port() const +{ + return d_func()->port; +} + +QString TomahawkSipMessage::uniqname() const +{ + return d_func()->uniqname; +} + +QString TomahawkSipMessage::key() const +{ + return d_func()->key; +} + +bool TomahawkSipMessage::visible() const +{ + return d_func()->visible; +} diff --git a/src/sip/jreen/tomahawksipmessage.h b/src/sip/jreen/tomahawksipmessage.h new file mode 100644 index 000000000..da1c376c5 --- /dev/null +++ b/src/sip/jreen/tomahawksipmessage.h @@ -0,0 +1,28 @@ +#ifndef ENTITYTIME_H +#define ENTITYTIME_H + +#include + +#define TOMAHAWK_SIP_MESSAGE_NS QLatin1String("http://www.tomhawk-player.org/sip/transports") + +class TomahawkSipMessagePrivate; +class TomahawkSipMessage : public Jreen::StanzaExtension +{ + J_EXTENSION(TomahawkSipMessage, "") + Q_DECLARE_PRIVATE(TomahawkSipMessage) + public: + TomahawkSipMessage(QString ip, unsigned int port, QString uniqname, QString key, bool visible); + // sets visible to false as we dont have any extra information + TomahawkSipMessage(); + ~TomahawkSipMessage(); + + const QString ip() const; + unsigned int port() const; + QString uniqname() const; + QString key() const; + bool visible() const; + private: + QScopedPointer d_ptr; +}; + +#endif // ENTITYTIME_H diff --git a/src/sip/jreen/tomahawksipmessagefactory.cpp b/src/sip/jreen/tomahawksipmessagefactory.cpp new file mode 100644 index 000000000..20a0a9ba8 --- /dev/null +++ b/src/sip/jreen/tomahawksipmessagefactory.cpp @@ -0,0 +1,124 @@ +#include "tomahawksipmessagefactory.h" +//#include "util.h" +#include +#include +#include +#include + +using namespace Jreen; + +TomahawkSipMessageFactory::TomahawkSipMessageFactory() +{ + m_depth = 0; + m_state = AtNowhere; +} + +TomahawkSipMessageFactory::~TomahawkSipMessageFactory() +{ +} + +QStringList TomahawkSipMessageFactory::features() const +{ + return QStringList(TOMAHAWK_SIP_MESSAGE_NS); +} + +bool TomahawkSipMessageFactory::canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes) +{ + Q_UNUSED(uri); + Q_UNUSED(attributes); + return name == QLatin1String("tomahawk") && uri == TOMAHAWK_SIP_MESSAGE_NS; +} + +void TomahawkSipMessageFactory::handleStartElement(const QStringRef &name, const QStringRef &uri, + const QXmlStreamAttributes &attributes) +{ + m_depth++; + if (m_depth == 1) { + m_state = AtNowhere; + m_ip = QString(); + m_port = -1; + m_uniqname = QString(); + m_key = QString(); + m_visible = false; + } else if (m_depth == 2) { + if (name == QLatin1String("transport")) + { + qDebug() << "Found Transport"; + m_state = AtTransport; + + m_uniqname = attributes.value(QLatin1String("uniqname")).toString(); + m_key = attributes.value(QLatin1String("pwd")).toString(); + m_visible = true; + } + } else if(m_depth == 3) { + if (name == QLatin1String("candidate")) + { + m_state = AtCandidate; + qDebug() << "Found candidate"; + m_ip = attributes.value(QLatin1String("ip")).toString(); + m_port = attributes.value(QLatin1String("port")).toString().toInt(); + + } + } + Q_UNUSED(uri); + Q_UNUSED(attributes); +} + +void TomahawkSipMessageFactory::handleEndElement(const QStringRef &name, const QStringRef &uri) +{ + if (m_depth == 3) + m_state = AtNowhere; + Q_UNUSED(name); + Q_UNUSED(uri); + m_depth--; +} + +void TomahawkSipMessageFactory::handleCharacterData(const QStringRef &text) +{ + /*if (m_state == AtUtc) { + //m_utc = Util::fromStamp(text.toString()); + } else if (m_state == AtTzo) { + QString str = text.toString(); + int multiple = str.startsWith('-') ? -1 : 1; + //QTime delta = QTime::fromString(str.mid(1), QLatin1String("hh:mm")); + //m_tzo = multiple * (delta.hour() * 60 + delta.minute()); + }*/ + Q_UNUSED(text); +} + +void TomahawkSipMessageFactory::serialize(StanzaExtension *extension, QXmlStreamWriter *writer) +{ + TomahawkSipMessage *sipMessage = se_cast(extension); + + writer->writeStartElement(QLatin1String("tomahawk")); + writer->writeDefaultNamespace(TOMAHAWK_SIP_MESSAGE_NS); + + if(sipMessage->visible()) + { + // add transport tag + writer->writeStartElement(QLatin1String("transport")); + writer->writeAttribute(QLatin1String("pwd"), sipMessage->key()); + writer->writeAttribute(QLatin1String("uniqname"), sipMessage->uniqname()); + + writer->writeEmptyElement(QLatin1String("candidate")); + writer->writeAttribute(QLatin1String("component"), "1"); + writer->writeAttribute(QLatin1String("id"), "el0747fg11"); // FIXME + writer->writeAttribute(QLatin1String("ip"), sipMessage->ip()); + writer->writeAttribute(QLatin1String("network"), "1"); + writer->writeAttribute(QLatin1String("port"), QVariant(sipMessage->port()).toString()); + writer->writeAttribute(QLatin1String("priority"), "1"); //TODO + writer->writeAttribute(QLatin1String("protocol"), "tcp"); + writer->writeAttribute(QLatin1String("type"), "host"); //FIXME: correct?! + writer->writeEndElement(); + } + else + { + writer->writeEmptyElement(QLatin1String("transport")); + } + writer->writeEndElement(); +} + +StanzaExtension::Ptr TomahawkSipMessageFactory::createExtension() +{ + return StanzaExtension::Ptr(new TomahawkSipMessage(m_ip, m_port, m_uniqname, m_key, m_visible)); +} diff --git a/src/sip/jreen/tomahawksipmessagefactory.h b/src/sip/jreen/tomahawksipmessagefactory.h new file mode 100644 index 000000000..318208710 --- /dev/null +++ b/src/sip/jreen/tomahawksipmessagefactory.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * + * This file is part of qutIM + * + * Copyright (c) 2011 by Nigmatullin Ruslan + * + *************************************************************************** + * * + * This file is part of 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 2 of the * + * License, or (at your option) any later version. * + * * + *************************************************************************** + ****************************************************************************/ + +#ifndef ENTITYTIMEFACTORY_P_H +#define ENTITYTIMEFACTORY_P_H + +#include "tomahawksipmessage.h" + +#include + +class TomahawkSipMessageFactory : public Jreen::StanzaExtensionFactory +{ +public: + TomahawkSipMessageFactory(); + virtual ~TomahawkSipMessageFactory(); + QStringList features() const; + bool canParse(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes); + void handleStartElement(const QStringRef &name, const QStringRef &uri, const QXmlStreamAttributes &attributes); + void handleEndElement(const QStringRef &name, const QStringRef &uri); + void handleCharacterData(const QStringRef &text); + void serialize(Jreen::StanzaExtension *extension, QXmlStreamWriter *writer); + Jreen::StanzaExtension::Ptr createExtension(); +private: + enum State { AtNowhere, AtTransport, AtCandidate } m_state; + int m_depth; + QString m_ip; + int m_port; + QString m_uniqname; + QString m_key; + bool m_visible; +}; + +#endif // ENTITYTIMEFACTORY_P_H From 0cfb98b0af175b0eb9410318d2ad7b7a4470de96 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 4 Apr 2011 21:14:05 +0200 Subject: [PATCH 06/29] Squash me --- src/sip/jreen/jabber_p.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 50e103c35..040616c44 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -19,6 +19,7 @@ #include "jabber_p.h" #include "tomahawksipmessage.h" +#include "tomahawksipmessagefactory.h" #include "config.h" #include "utils/tomahawkutils.h" @@ -53,6 +54,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& // general client setup m_client = new Jreen::Client( jid, password ); + m_client->registerStanzaExtension(new TomahawkSipMessageFactory); m_client->setResource( QString( "DISABLEDtomahawk%1" ).arg( qrand() ) ); // setup disco @@ -149,13 +151,16 @@ Jabber_p::sendMsg( const QString& to, const QString& msg ) Jreen::IQ iq( Jreen::IQ::Set, to ); iq.addExtension( sipMessage ); - m_client->send( iq, this, SLOT( onNewIQ( Jreen::IQ, int ) ), SipMessageSent ); + m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), SipMessageSent ); } void Jabber_p::broadcastMsg( const QString &msg ) { + QString *foobar; + foobar->append("blabla"); + qDebug() << Q_FUNC_INFO; if ( !m_client ) @@ -328,7 +333,7 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) Jreen::IQ iq( Jreen::IQ::Get, jid ); iq.addExtension( new Jreen::Disco::Info( node ) ); - m_client->send( iq, this, SLOT( onNewIQ( Jreen::IQ, int ) ), RequestDisco ); + m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), RequestDisco ); } else if( !caps ) { From 3a0874bcddbd796e5c9a3919a51463fb94e6cc54 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 4 Apr 2011 23:20:35 +0200 Subject: [PATCH 07/29] More debug and fails-- --- src/sip/jreen/jabber_p.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 040616c44..5de047872 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -64,8 +64,8 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& // setup caps node, legacy peer detection - used before 0.1 // disable it for testing - //Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); - //caps->setNode(TOMAHAWK_CAP_NODE_NAME); + Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); + caps->setNode(TOMAHAWK_CAP_NODE_NAME); // print connection parameters qDebug() << "Our JID set to:" << m_client->jid().full(); @@ -79,6 +79,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& connect(m_client, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroy())); connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message))); connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence))); + connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIQ(Jreen::IQ))); // connect @@ -344,6 +345,7 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) void Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) { + qDebug() << Q_FUNC_INFO; if( context == RequestDisco ) { qDebug() << Q_FUNC_INFO << "Received disco IQ..."; @@ -371,12 +373,16 @@ Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) { qDebug() << "Sent IQ(Set), what should be happening here?"; } + else if(context == SipMessageSent ) + { + qDebug() << "Sent SipMessage... what now?!"; + } else { + qDebug() << Q_FUNC_INFO << "No context!"; TomahawkSipMessage *sipMessage = iq.findExtension().data(); if(sipMessage) { - qDebug() << Q_FUNC_INFO << "Got SipMessage ..."; qDebug() << "ip" << sipMessage->ip(); qDebug() << "port" << sipMessage->port(); From 4cb2532fabe3b7af85a3c93d4c80f6eb1973ab73 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 4 Apr 2011 23:22:49 +0200 Subject: [PATCH 08/29] Heyyeeyeeey - hey stupid --- src/sip/jreen/jabber_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 5de047872..99e4f1b9b 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -79,7 +79,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& connect(m_client, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroy())); connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message))); connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence))); - connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIQ(Jreen::IQ))); + connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ))); // connect From e944293d02a472e11a11c6be716c754f022376b1 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 5 Apr 2011 17:14:11 +0200 Subject: [PATCH 09/29] Build jreen on default --- CMakeLists.txt | 4 ++-- src/sip/CMakeLists.txt | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a19ec507c..9d40b2c3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) # optional macro_optional_find_package(Jreen) -IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) +IF( NOT LIBJREEN_FOUND ) ADD_SUBDIRECTORY( thirdparty/jreen ) SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) IF( UNIX AND NOT APPLE ) @@ -65,7 +65,7 @@ IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) ENDIF( WIN32 ) SET( LIBJREEN_FOUND true ) MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") -ENDIF( ENABLE_JREEN AND NOT LIBJREEN_FOUND ) +ENDIF( NOT LIBJREEN_FOUND ) IF( WIN32 ) find_library(QTSPARKLE_LIBRARIES qtsparkle) diff --git a/src/sip/CMakeLists.txt b/src/sip/CMakeLists.txt index 82aa3ae97..3e547058a 100644 --- a/src/sip/CMakeLists.txt +++ b/src/sip/CMakeLists.txt @@ -1,10 +1,11 @@ # only build one of them, if ENABLE_JREEN is true, GLOOX_FOUND is automatically set to "false" -IF( GLOOX_FOUND ) +IF( GLOOX_FOUND AND NOT LIBJREEN_FOUND ) ADD_SUBDIRECTORY( jabber ) -ENDIF( GLOOX_FOUND ) -IF( ENABLE_JREEN ) +ENDIF( GLOOX_FOUND AND NOT LIBJREEN_FOUND ) + +IF( LIBJREEN_FOUND ) ADD_SUBDIRECTORY( jreen ) -ENDIF( ENABLE_JREEN) +ENDIF( LIBJREEN_FOUND ) ADD_SUBDIRECTORY( twitter ) ADD_SUBDIRECTORY( zeroconf ) From 9d95644b9f1bce613cd3d4788dcfc3d48f86cbb2 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 5 Apr 2011 17:15:02 +0200 Subject: [PATCH 10/29] Add debug when sending messages --- src/sip/jreen/jabber_p.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 99e4f1b9b..59a0ee25e 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -118,6 +118,8 @@ Jabber_p::sendMsg( const QString& to, const QString& msg ) return; } + qDebug() << "SEND MESSAGE:" << msg; + /******************************************************* * Obsolete this by a SipMessage class */ From c1385761b6aa1e8c2b04bf7e7b207fe22e162d26 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 6 Apr 2011 06:43:24 +0200 Subject: [PATCH 11/29] Find jreen headers in source, HACK --- src/sip/jreen/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sip/jreen/CMakeLists.txt b/src/sip/jreen/CMakeLists.txt index 7cf3d3dd2..50f33a7c6 100644 --- a/src/sip/jreen/CMakeLists.txt +++ b/src/sip/jreen/CMakeLists.txt @@ -23,6 +23,7 @@ set( jabberHeaders include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ${QT_INCLUDE_DIR} ${LIBJREEN_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/thirdparty/jreen/src/ ) qt4_wrap_cpp( jabberMoc ${jabberHeaders} ) From cadc72da2e2d9eec292dbdd1e75724dcd0c14eff Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sat, 16 Apr 2011 17:27:39 +0200 Subject: [PATCH 12/29] sipjreen: Clean up debug output and add legacy mode --- src/sip/jreen/jabber_p.cpp | 54 +++++++++++++++++++++++++------------- src/sip/jreen/jabber_p.h | 2 ++ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 1c774483f..c624e1123 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -55,7 +55,7 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& // general client setup m_client = new Jreen::Client( jid, password ); m_client->registerStanzaExtension(new TomahawkSipMessageFactory); - m_client->setResource( QString( "DISABLEDtomahawk%1" ).arg( QString::number( qrand() % 10000 ) ) ); + m_client->setResource( QString( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ) ); // setup disco m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM ); @@ -63,9 +63,8 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& m_client->disco()->addFeature( TOMAHAWK_FEATURE ); // setup caps node, legacy peer detection - used before 0.1 - // disable it for testing Jreen::Capabilities::Ptr caps = m_client->presence().findExtension(); - caps->setNode(TOMAHAWK_CAP_NODE_NAME); + caps->setNode( TOMAHAWK_CAP_NODE_NAME ); // print connection parameters qDebug() << "Our JID set to:" << m_client->jid().full(); @@ -112,13 +111,21 @@ Jabber_p::disconnect() void Jabber_p::sendMsg( const QString& to, const QString& msg ) { - qDebug() << Q_FUNC_INFO; + qDebug() << Q_FUNC_INFO << to << msg; if ( !m_client ) { return; } - qDebug() << "SEND MESSAGE:" << msg; + if( m_legacy_peers.contains( to ) ) + { + qDebug() << Q_FUNC_INFO << to << "Send legacy message" << msg; + Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg); + m_client->send( m ); + + return; + } + /******************************************************* * Obsolete this by a SipMessage class @@ -161,9 +168,6 @@ Jabber_p::sendMsg( const QString& to, const QString& msg ) void Jabber_p::broadcastMsg( const QString &msg ) { - QString *foobar; - foobar->append("blabla"); - qDebug() << Q_FUNC_INFO; if ( !m_client ) @@ -171,9 +175,7 @@ Jabber_p::broadcastMsg( const QString &msg ) foreach( const QString& jidstr, m_peers.keys() ) { - qDebug() << "Broadcasting to" << jidstr <<"..."; - Jreen::Message m( Jreen::Message::Chat, Jreen::JID(jidstr), msg, "" ); - m_client->send( m ); + sendMsg( jidstr, msg ); } } @@ -224,8 +226,8 @@ Jabber_p::onConnect() //m_room->join(); // treat muc participiants like contacts - connect(m_room, SIGNAL(messageReceived(Jreen::Message, bool)), this, SLOT(onNewMessage(Jreen::Message))); - connect(m_room, SIGNAL(presenceReceived(Jreen::Presence,const Jreen::MUCRoom::Participant*)), this, SLOT(onNewPresence(Jreen::Presence))); + connect( m_room, SIGNAL( messageReceived( Jreen::Message, bool ) ), this, SLOT( onNewMessage( Jreen::Message ) ) ); + connect( m_room, SIGNAL( presenceReceived( Jreen::Presence, const Jreen::MUCRoom::Participant* ) ), this, SLOT( onNewPresence( Jreen::Presence ) ) ); } @@ -313,15 +315,15 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) return; if ( presence.error() ) { - qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error"; + //qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error"; return; } // ignore anyone not Running tomahawk: Jreen::Capabilities::Ptr caps = presence.findExtension(); - if ( caps && (caps->node() == TOMAHAWK_CAP_NODE_NAME ) && false) // disable this method to test the new one + if ( caps && ( caps->node() == TOMAHAWK_CAP_NODE_NAME ) ) { - // legacy peer detection + // must be a jreen resource, implementation in gloox was broken qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node(); handlePeerStatus( fulljid, presence.subtype() ); } @@ -347,7 +349,6 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) void Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) { - qDebug() << Q_FUNC_INFO; if( context == RequestDisco ) { qDebug() << Q_FUNC_INFO << "Received disco IQ..."; @@ -369,6 +370,17 @@ Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) else { qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: no"; + + //LEGACY: accept resources starting with tomahawk too + if( iq.from().resource().startsWith("tomahawk") ) + { + qDebug() << Q_FUNC_INFO << fulljid << "Detected legacy tomahawk.."; + + // add to legacy peers, so we can send text messages instead of iqs + m_legacy_peers.append( fulljid ); + + handlePeerStatus( fulljid, Jreen::Presence::Available ); + } } } else if(context == RequestedDisco) @@ -381,7 +393,6 @@ Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) } else { - qDebug() << Q_FUNC_INFO << "No context!"; TomahawkSipMessage *sipMessage = iq.findExtension().data(); if(sipMessage) { @@ -446,6 +457,13 @@ Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presen { m_peers[ fulljid ] = presenceType; qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid; + + // remove peer from legacy peers + if( m_legacy_peers.contains( fulljid ) ) + { + m_legacy_peers.removeAll( fulljid ); + } + emit peerOffline( fulljid ); return; } diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index be5edeeb8..ae00f1329 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -96,6 +96,8 @@ private: QString m_server; enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent }; + + QStringList m_legacy_peers; }; #endif // JABBER_H From b52b87f818b8ca43942d13a2c2b60077d042baf3 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 17 Apr 2011 19:49:03 +0200 Subject: [PATCH 13/29] Updated jreen submodule --- thirdparty/jreen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/jreen b/thirdparty/jreen index 126ef9d96..ff5d1fdc9 160000 --- a/thirdparty/jreen +++ b/thirdparty/jreen @@ -1 +1 @@ -Subproject commit 126ef9d96bf774b9808a16dd8c94001af408528b +Subproject commit ff5d1fdc9f416a0e10e1e571e51a70ca377e6811 From 5b01ae52681f35ffc674dc8ca674ef82e590ac3f Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 17 Apr 2011 21:25:24 +0200 Subject: [PATCH 14/29] On default use system jreen package, allow the user to enforce in-tree compilation with -DINTERNAL_JREEN=ON. --- CMakeLists.txt | 39 ++++++++++++++++++++---------------- CMakeModules/FindJreen.cmake | 8 +++++--- src/sip/jreen/CMakeLists.txt | 1 - thirdparty/CMakeLists.txt | 4 ++-- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc5a74825..7cd00c3c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,28 @@ macro_log_feature(QJSON_FOUND "QJson" "Qt library that maps JSON data to QVarian macro_optional_find_package(Taglib 1.6.0) macro_log_feature(TAGLIB_FOUND "TagLib" "Audio Meta-Data Library" "http://developer.kde.org/~wheeler/taglib.html" TRUE "" "taglib is needed for reading meta data from audio files") +# this installs headers and such and should really be handled in a separate package by packagers +IF( INTERNAL_JREEN ) + ADD_SUBDIRECTORY( thirdparty/jreen ) + SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) + + IF( UNIX AND NOT APPLE ) + SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so ) + ENDIF( UNIX AND NOT APPLE ) + IF( APPLE ) + SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dylib ) + ENDIF( APPLE ) + IF( WIN32 ) + SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) + ENDIF( WIN32 ) + + SET( LIBJREEN_FOUND true ) + MESSAGE(STATUS "INTERNAL libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") +ELSE( INTERNAL_JREEN ) + macro_optional_find_package(Jreen) +ENDIF( INTERNAL_JREEN ) +macro_log_feature(LIBJREEN_FOUND "Jreen" "Qt XMPP Library" "http://gitorious.org/jreen/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin. \n\n Use -DINTERNAL_JREEN=ON to build the git submodule inside Tomahawk \n Be aware this installs a full jreen with headers and everything!") + # we need pthreads too find_package(Threads) @@ -65,23 +87,6 @@ ENDIF() include( CheckTagLibFileName ) check_taglib_filename( COMPLEX_TAGLIB_FILENAME ) -# optional -macro_optional_find_package(Jreen) -IF( NOT LIBJREEN_FOUND ) - SET( CMAKE_C_FLAGS ${CLEAN_C_FLAGS} ) - ADD_SUBDIRECTORY( thirdparty/jreen ) - SET( LIBJREEN_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/include ) - IF( UNIX AND NOT APPLE ) - SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.so ) - ENDIF( UNIX AND NOT APPLE ) - IF( WIN32 ) - SET( LIBJREEN_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/thirdparty/jreen/libjreen.dll ) - ENDIF( WIN32 ) - SET( LIBJREEN_FOUND true ) - MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") -ENDIF( NOT LIBJREEN_FOUND ) - - IF( WIN32 ) find_library(QTSPARKLE_LIBRARIES qtsparkle) ENDIF( WIN32 ) diff --git a/CMakeModules/FindJreen.cmake b/CMakeModules/FindJreen.cmake index 301eb24e7..9174ca65a 100644 --- a/CMakeModules/FindJreen.cmake +++ b/CMakeModules/FindJreen.cmake @@ -6,15 +6,15 @@ # LIBJREEN_FOUND, whether libjreen was found -find_path(LIBJREEN_INCLUDE_DIR NAMES jreen.h +find_path(LIBJREEN_INCLUDE_DIR NAMES jreen/jreen.h HINTS ~/usr/include /opt/local/include /usr/include /usr/local/include /opt/kde4/include + ${CMAKE_INSTALL_PREFIX}/include ${KDE4_INCLUDE_DIR} - PATH_SUFFIXES jreen ) find_library( LIBJREEN_LIBRARY NAMES jreen @@ -25,6 +25,8 @@ find_library( LIBJREEN_LIBRARY NAMES jreen /usr/lib64 /usr/local/lib /opt/kde4/lib + ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib64 ${KDE4_LIB_DIR} ) @@ -33,7 +35,7 @@ if(LIBJREEN_INCLUDE_DIR AND LIBJREEN_LIBRARY) set(LIBJREEN_FOUND TRUE) message(STATUS "Found libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}") else(LIBJREEN_INCLUDE_DIR AND LIBJREEN_LIBRARY) - set(LIBJREEN_FOUND FALSE) + set(LIBJREEN_FOUND FALSE) if (LIBJREEN_FIND_REQUIRED) message(FATAL_ERROR "Could NOT find required package libjreen") endif(LIBJREEN_FIND_REQUIRED) diff --git a/src/sip/jreen/CMakeLists.txt b/src/sip/jreen/CMakeLists.txt index 50f33a7c6..7cf3d3dd2 100644 --- a/src/sip/jreen/CMakeLists.txt +++ b/src/sip/jreen/CMakeLists.txt @@ -23,7 +23,6 @@ set( jabberHeaders include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. ${QT_INCLUDE_DIR} ${LIBJREEN_INCLUDE_DIR} - ${CMAKE_SOURCE_DIR}/thirdparty/jreen/src/ ) qt4_wrap_cpp( jabberMoc ${jabberHeaders} ) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index f28fdff43..dc734eac2 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -1,5 +1,5 @@ -add_subdirectory( jdns ) -add_subdirectory( qtweetlib ) +ADD_SUBDIRECTORY( jdns ) +ADD_SUBDIRECTORY( qtweetlib ) ADD_SUBDIRECTORY( libportfwd ) ADD_SUBDIRECTORY( qxt ) ADD_SUBDIRECTORY( liblastfm2 ) From 309024a4675f18885637e655bfc3fb3bbdcd2884 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 18 Apr 2011 10:40:45 -0400 Subject: [PATCH 15/29] Switch some calls from InfoCustomData to InfoCriteriaHash, much simplifying --- src/audiocontrols.cpp | 8 ++-- .../infosystem/infoplugins/lastfmplugin.cpp | 37 ++++++++++--------- src/libtomahawk/playlist/artistview.cpp | 8 ++-- src/libtomahawk/playlist/treemodel.cpp | 15 ++++---- src/scrobbler.cpp | 12 +++--- 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index d80efd846..e856d3c3b 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -213,13 +213,13 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) onPlaybackLoading( result ); - Tomahawk::InfoSystem::InfoCustomData trackInfo; - trackInfo["artist"] = QVariant::fromValue< QString >( result->artist()->name() ); - trackInfo["album"] = QVariant::fromValue< QString >( result->album()->name() ); + Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; + trackInfo["artist"] = result->artist()->name(); + trackInfo["album"] = result->album()->name(); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_acInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } diff --git a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp index 20f09981e..d34367008 100644 --- a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp @@ -134,12 +134,12 @@ LastFmPlugin::getInfo( const QString &caller, const InfoType type, const QVarian void LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { - if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() || !m_scrobbler ) + if ( !data.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() || !m_scrobbler ) { dataError( caller, type, data, customData ); return; } - InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >(); + InfoCriteriaHash hash = data.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) ) { dataError( caller, type, data, customData ); @@ -149,10 +149,11 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar m_track = lastfm::MutableTrack(); m_track.stamp(); - m_track.setTitle( hash["title"].toString() ); - m_track.setArtist( hash["artist"].toString() ); - m_track.setAlbum( hash["album"].toString() ); - m_track.setDuration( hash["duration"].toUInt() ); + m_track.setTitle( hash["title"] ); + m_track.setArtist( hash["artist"] ); + m_track.setAlbum( hash["album"] ); + bool ok; + m_track.setDuration( hash["duration"].toUInt( &ok ) ); m_track.setSource( lastfm::Track::Player ); m_scrobbler->nowPlaying( m_track ); @@ -183,12 +184,12 @@ void LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { qDebug() << Q_FUNC_INFO; - if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( !data.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { dataError( caller, type, data, customData ); return; } - InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >(); + InfoCriteriaHash hash = data.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) || !hash.contains( "album" ) ) { dataError( caller, type, data, customData ); @@ -196,8 +197,8 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q } Tomahawk::InfoSystem::InfoCriteriaHash criteria; - criteria["artist"] = hash["artist"].toString(); - criteria["album"] = hash["album"].toString(); + criteria["artist"] = hash["artist"]; + criteria["album"] = hash["album"]; emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); } @@ -207,12 +208,12 @@ void LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant& data, Tomahawk::InfoSystem::InfoCustomData &customData ) { qDebug() << Q_FUNC_INFO; - if ( !data.canConvert< Tomahawk::InfoSystem::InfoCustomData >() ) + if ( !data.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) { dataError( caller, type, data, customData ); return; } - InfoCustomData hash = data.value< Tomahawk::InfoSystem::InfoCustomData >(); + InfoCriteriaHash hash = data.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "artist" ) ) { dataError( caller, type, data, customData ); @@ -220,7 +221,7 @@ LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, con } Tomahawk::InfoSystem::InfoCriteriaHash criteria; - criteria["artist"] = hash["artist"].toString(); + criteria["artist"] = hash["artist"]; emit getCachedInfo( criteria, 2419200000, caller, type, data, customData ); } @@ -301,10 +302,10 @@ LastFmPlugin::coverArtReturned() customData ); - InfoCustomData origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; - criteria["artist"] = origData["artist"].toString(); - criteria["album"] = origData["album"].toString(); + criteria["artist"] = origData["artist"]; + criteria["album"] = origData["album"]; emit updateCache( criteria, 2419200000, type, returnedData ); } else @@ -352,9 +353,9 @@ LastFmPlugin::artistImagesReturned() customData ); - InfoCustomData origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCustomData >(); + InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCriteriaHash criteria; - criteria["artist"] = origData["artist"].toString(); + criteria["artist"] = origData["artist"]; emit updateCache( criteria, 2419200000, type, returnedData ); } else diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 126f99ecd..722183762 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -223,12 +223,12 @@ ArtistView::onScrollTimeout() { TreeModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) ); - Tomahawk::InfoSystem::InfoCustomData trackInfo; - trackInfo["artist"] = QVariant::fromValue< QString >( item->artist()->name() ); - trackInfo["pptr"] = QVariant::fromValue< qlonglong >( (qlonglong)item ); + Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; + trackInfo["artist"] = item->artist()->name(); + trackInfo["pptr"] = QString::number( (qlonglong)item ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } } diff --git a/src/libtomahawk/playlist/treemodel.cpp b/src/libtomahawk/playlist/treemodel.cpp index 7d7974974..8830e0bfe 100644 --- a/src/libtomahawk/playlist/treemodel.cpp +++ b/src/libtomahawk/playlist/treemodel.cpp @@ -476,14 +476,14 @@ TreeModel::onAlbumsAdded( const QList& albums, const QVaria albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem ); connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) ); - Tomahawk::InfoSystem::InfoCustomData trackInfo; - trackInfo["artist"] = QVariant::fromValue< QString >( album->artist()->name() ); - trackInfo["album"] = QVariant::fromValue< QString >( album->name() ); - trackInfo["pptr"] = QVariant::fromValue< qlonglong >( (qlonglong)albumitem ); + Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; + trackInfo["artist"] = album->artist()->name(); + trackInfo["album"] = album->name(); + trackInfo["pptr"] = QString::number( (qlonglong)albumitem ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); } if ( crows.second > 0 ) @@ -555,7 +555,7 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, return; } - Tomahawk::InfoSystem::InfoCustomData pptr = input.value< Tomahawk::InfoSystem::InfoCustomData >(); + Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >(); const QByteArray ba = returnedData["imgbytes"].toByteArray(); if ( ba.length() ) @@ -563,7 +563,8 @@ TreeModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QPixmap pm; pm.loadFromData( ba ); - qlonglong p = pptr["pptr"].toLongLong(); + bool ok; + qlonglong p = pptr["pptr"].toLongLong( &ok ); TreeModelItem* ai = reinterpret_cast(p); if ( pm.isNull() ) diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index 74ad40ae8..2c5d572b4 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -74,15 +74,15 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track ) scrobble(); } - Tomahawk::InfoSystem::InfoCustomData trackInfo; + Tomahawk::InfoSystem::InfoCriteriaHash trackInfo; - trackInfo["title"] = QVariant::fromValue< QString >( track->track() ); - trackInfo["artist"] = QVariant::fromValue< QString >( track->artist()->name() ); - trackInfo["album"] = QVariant::fromValue< QString >( track->album()->name() ); - trackInfo["duration"] = QVariant::fromValue< uint >( track->duration() ); + trackInfo["title"] = track->track(); + trackInfo["artist"] = track->artist()->name(); + trackInfo["album"] = track->album()->name(); + trackInfo["duration"] = QString::number( track->duration() ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( s_scInfoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying, - QVariant::fromValue< Tomahawk::InfoSystem::InfoCustomData >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() ); m_scrobblePoint = ScrobblePoint( track->duration() / 2 ); } From 35d51a2cd209cb4847ba9d4a0249d581d8f8f3c0 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Sun, 17 Apr 2011 22:32:18 +0200 Subject: [PATCH 16/29] sipjreen: Fix some signal and slot connections --- src/sip/jreen/jabber.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sip/jreen/jabber.cpp b/src/sip/jreen/jabber.cpp index 2c40bbb5f..6a3f3fa71 100644 --- a/src/sip/jreen/jabber.cpp +++ b/src/sip/jreen/jabber.cpp @@ -106,8 +106,8 @@ JabberPlugin::connectPlugin( bool startup ) QObject::connect( p, SIGNAL( peerOffline( QString ) ), SIGNAL( peerOffline( QString ) ) ); QObject::connect( p, SIGNAL( msgReceived( QString, QString ) ), SIGNAL( msgReceived( QString, QString ) ) ); - QObject::connect( p, SIGNAL( connected() ), SIGNAL( onConnected() ) ); - QObject::connect( p, SIGNAL( disconnected() ), SIGNAL( onDisconnected() ) ); + QObject::connect( p, SIGNAL( connected() ), SLOT( onConnected() ) ); + QObject::connect( p, SIGNAL( disconnected() ), SLOT( onDisconnected() ) ); return true; } From 01980ab6d1ae160ea99fcef7210c783a608a673e Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 18 Apr 2011 10:21:04 +0200 Subject: [PATCH 17/29] sipjreen: Add authError signal --- src/sip/jreen/jabber.cpp | 29 +++++++++++++++++++++++++++++ src/sip/jreen/jabber.h | 1 + src/sip/jreen/jabber_p.cpp | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/src/sip/jreen/jabber.cpp b/src/sip/jreen/jabber.cpp index 6a3f3fa71..a4b0f1aab 100644 --- a/src/sip/jreen/jabber.cpp +++ b/src/sip/jreen/jabber.cpp @@ -109,6 +109,8 @@ JabberPlugin::connectPlugin( bool startup ) QObject::connect( p, SIGNAL( connected() ), SLOT( onConnected() ) ); QObject::connect( p, SIGNAL( disconnected() ), SLOT( onDisconnected() ) ); + QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) ); + return true; } @@ -156,6 +158,33 @@ JabberPlugin::onDisconnected() emit disconnected(); } +void +JabberPlugin::onAuthError( int code, const QString& msg ) +{ + switch( code ) + { + case Jreen::Client::AuthorizationError: + emit error( SipPlugin::AuthError, msg ); + break; + + case Jreen::Client::HostUnknown: + case Jreen::Client::ItemNotFound: + case Jreen::Client::RemoteStreamError: + case Jreen::Client::RemoteConnectionFailed: + case Jreen::Client::InternalServerError: + case Jreen::Client::SystemShutdown: + case Jreen::Client::Conflict: + case Jreen::Client::Unknown: + emit error( SipPlugin::ConnectionError, msg ); + break; + + default: + qDebug() << "Not all Client::DisconnectReasons checked"; + Q_ASSERT(false); + break; + } +} + void JabberPlugin::sendMsg(const QString& to, const QString& msg) { diff --git a/src/sip/jreen/jabber.h b/src/sip/jreen/jabber.h index 080ff78c3..75996381d 100644 --- a/src/sip/jreen/jabber.h +++ b/src/sip/jreen/jabber.h @@ -57,6 +57,7 @@ private slots: void showAddFriendDialog(); void onConnected(); void onDisconnected(); + void onAuthError(int code, const QString &msg); private: Jabber_p* p; diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index c624e1123..2fcd6e0e8 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -283,6 +283,10 @@ Jabber_p::onDisconnect( Jreen::Client::DisconnectReason reason ) } qDebug() << "Disconnected from server:" << error; + if( reason != Jreen::Client::User ) + { + emit authError( reason, error ); + } if(reconnect) QTimer::singleShot(reconnectInSeconds*1000, m_client, SLOT(connectToServer())); From 04b4c69ab3cb39695cb5092ac1ca6ce33f3b52b5 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 18 Apr 2011 22:18:12 +0200 Subject: [PATCH 18/29] sipjreen: Add I'm-not-a-person-auto-response --- src/sip/jreen/jabber_p.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 2fcd6e0e8..5c849f40c 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -303,6 +303,22 @@ Jabber_p::onNewMessage( const Jreen::Message& m ) if ( msg.isEmpty() ) return; + QJson::Parser parser; + bool ok; + QVariant v = parser.parse( msg.toAscii(), &ok ); + if ( !ok || v.type() != QVariant::Map ) + { + QString to = from; + QString response = QString( tr("I'm sorry -- I'm just an automatic presence used by Tomahawk Player" + " (http://gettomahawk.com). If you are getting this message, the person you" + " are trying to reach is probably not signed on, so please try again later!") ); + + // this is not a sip message, so we send it directly through the client + m_client->send( Jreen::Message ( Jreen::Message::Chat, Jreen::JID(to), response) ); + + return; + } + qDebug() << Q_FUNC_INFO << "From:" << m.from().full() << ":" << m.body(); emit msgReceived( from, msg ); } From d87398c47aee5e2b56b072d9084a803c3efa1d2a Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 20 Apr 2011 00:26:13 +0200 Subject: [PATCH 19/29] First shitty implementation of loading avatars --- src/sip/jreen/jabber_p.cpp | 42 ++++++++++++++++++++++++++++++++++++-- src/sip/jreen/jabber_p.h | 9 ++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 5c849f40c..93efa5a06 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -25,6 +25,8 @@ #include "utils/tomahawkutils.h" #include +#include +#include #include #include @@ -37,6 +39,14 @@ #include #include #include +#include +#include +#include +#include + +//remove +#include +#include #define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" ) @@ -57,6 +67,12 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& m_client->registerStanzaExtension(new TomahawkSipMessageFactory); m_client->setResource( QString( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ) ); + // add VCardUpdate extension to own presence + m_client->presence().addExtension( new Jreen::VCardUpdate() ); + + // read cached avatars + m_photoHashes = QDir("/home/domme/jreen/").entryList(); + // setup disco m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM ); m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) ); @@ -210,6 +226,9 @@ Jabber_p::onConnect() // set presence to least valid value m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127); + // request own vcard + fetchVCard( m_jid.bare() ); + // set ping timeout to 15 secs (TODO: verify if this works) m_client->setPingInterval(15000); @@ -329,8 +348,19 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) Jreen::JID jid = presence.from(); QString fulljid( jid.full() ); + qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype(); + Jreen::VCardUpdate::Ptr update = presence.findExtension(); + if(update) + { + qDebug() << "vcard: found update for " << fulljid; + if(!m_photoHashes.contains(update->photoHash())) + { + fetchVCard( jid.bare() ); + } + } + if( jid == m_jid ) return; @@ -411,11 +441,18 @@ Jabber_p::onNewIq( const Jreen::IQ &iq, int context ) { qDebug() << "Sent SipMessage... what now?!"; } + /*else if(context == RequestedVCard ) + { + qDebug() << "Requested VCard... what now?!"; + }*/ else { + TomahawkSipMessage *sipMessage = iq.findExtension().data(); if(sipMessage) { + iq.accept(); + qDebug() << Q_FUNC_INFO << "Got SipMessage ..."; qDebug() << "ip" << sipMessage->ip(); qDebug() << "port" << sipMessage->port(); @@ -466,8 +503,10 @@ Jabber_p::presenceMeansOnline( Jreen::Presence::Type p ) } void -Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presenceType ) +Jabber_p::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenceType ) { + QString fulljid = jid.full(); + // "going offline" event if ( !presenceMeansOnline( presenceType ) && ( !m_peers.contains( fulljid ) || @@ -504,4 +543,3 @@ Jabber_p::handlePeerStatus( const QString& fulljid, Jreen::Presence::Type presen //qDebug() << "Updating presence data for" << fulljid; m_peers[ fulljid ] = presenceType; } - diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index ae00f1329..0fd354467 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -85,7 +85,7 @@ private slots: private: bool presenceMeansOnline( Jreen::Presence::Type p ); - void handlePeerStatus( const QString &fulljid, Jreen::Presence::Type presenceType ); + void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType ); Jreen::Client *m_client; Jreen::MUCRoom *m_room; @@ -95,9 +95,14 @@ private: QMap m_peers; QString m_server; - enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent }; + enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard }; QStringList m_legacy_peers; + + + //sort out + //QHash m_contactsPhotoHashes; + QStringList m_photoHashes; }; #endif // JABBER_H From cbd51960806fedbcfe5896ea45739fa911895496 Mon Sep 17 00:00:00 2001 From: Alejandro Wainzinger Date: Tue, 19 Apr 2011 22:26:18 -0400 Subject: [PATCH 20/29] Fix CMake. --- src/CMakeLists.osx.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.osx.txt b/src/CMakeLists.osx.txt index 0488b2f71..9d43c8e65 100644 --- a/src/CMakeLists.osx.txt +++ b/src/CMakeLists.osx.txt @@ -37,7 +37,7 @@ if (APPLE) # We have to change the URL in the Info.plist file :-/ FILE(READ ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist plist) STRING( REPLACE "TOMAHAWK_VERSION" - ${VERSION} + ${TOMAHAWK_VERSION} edited_plist # save in this variable "${plist}" # from the contents of this var ) From 2e80475a9d89cfeaf569c8c30d34d9484b87e651 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Wed, 20 Apr 2011 16:21:12 +0200 Subject: [PATCH 21/29] * Moved --demo stuff to Source class. --- include/tomahawk/tomahawkapp.h | 3 --- src/libtomahawk/source.cpp | 24 +++++++++++++++++------- src/libtomahawk/source.h | 3 ++- src/sourcetree/sourcetreeitem.cpp | 15 +++++---------- src/sourcetree/sourcetreeview.cpp | 2 +- src/tomahawkapp.cpp | 2 -- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/include/tomahawk/tomahawkapp.h b/include/tomahawk/tomahawkapp.h index 2d55f3a1b..1547254dd 100644 --- a/include/tomahawk/tomahawkapp.h +++ b/include/tomahawk/tomahawkapp.h @@ -98,9 +98,6 @@ public: virtual void activate(); virtual bool loadUrl( const QString& url ); - // because QApplication::arguments() is expensive - bool scrubFriendlyName() const { return m_scrubFriendlyName; } - public slots: void instanceStarted( KDSingleApplicationGuard::Instance ); diff --git a/src/libtomahawk/source.cpp b/src/libtomahawk/source.cpp index d825a7724..46acb5857 100644 --- a/src/libtomahawk/source.cpp +++ b/src/libtomahawk/source.cpp @@ -27,6 +27,8 @@ #include "database/databasecommand_logplayback.h" #include "database/database.h" +#include + using namespace Tomahawk; @@ -40,6 +42,8 @@ Source::Source( int id, const QString& username ) { qDebug() << Q_FUNC_INFO << id << username; + m_scrubFriendlyName = qApp->arguments().contains( "--demo" ); + if ( id == 0 ) { m_isLocal = true; @@ -98,8 +102,8 @@ Source::friendlyName() const return m_username; //TODO: this is a terrible assumption, help me clean this up, mighty muesli! - if ( m_friendlyname.contains( "@conference.") ) - return QString(m_friendlyname).remove( 0, m_friendlyname.lastIndexOf( "/" )+1 ).append(" via MUC"); + if ( m_friendlyname.contains( "@conference." ) ) + return QString( m_friendlyname ).remove( 0, m_friendlyname.lastIndexOf( "/" ) + 1 ).append( " via MUC" ); if ( m_friendlyname.contains( "/tomahawk" ) ) return m_friendlyname.left( m_friendlyname.indexOf( "/tomahawk" ) ); @@ -108,6 +112,15 @@ Source::friendlyName() const } +void +Source::setFriendlyName( const QString& fname ) +{ + m_friendlyname = fname; + if ( m_scrubFriendlyName ) + m_friendlyname = m_friendlyname.split( "@" ).first(); +} + + void Source::addCollection( const collection_ptr& c ) { @@ -164,7 +177,7 @@ Source::dbLoaded( unsigned int id, const QString& fname ) qDebug() << Q_FUNC_INFO << id << fname; m_id = id; - m_friendlyname = fname; + setFriendlyName( fname ); emit syncedWithDatabase(); } @@ -225,10 +238,7 @@ Source::onStateChanged( DBSyncConnection::State newstate, DBSyncConnection::Stat unsigned int Source::trackCount() const { - if ( m_stats.contains( "numfiles" ) ) - return m_stats.value( "numfiles" ).toUInt(); - else - return 0; + return m_stats.value( "numfiles" ).toUInt(); } diff --git a/src/libtomahawk/source.h b/src/libtomahawk/source.h index ed48dfd1b..0f8b766c9 100644 --- a/src/libtomahawk/source.h +++ b/src/libtomahawk/source.h @@ -53,7 +53,7 @@ public: QString userName() const { return m_username; } QString friendlyName() const; - void setFriendlyName( const QString& fname ) { m_friendlyname = fname; } + void setFriendlyName( const QString& fname ); collection_ptr collection() const; void addCollection( const Tomahawk::collection_ptr& c ); @@ -111,6 +111,7 @@ private: QList< QSharedPointer > m_collections; QVariantMap m_stats; QString m_lastOpGuid; + bool m_scrubFriendlyName; Tomahawk::query_ptr m_currentTrack; QString m_textStatus; diff --git a/src/sourcetree/sourcetreeitem.cpp b/src/sourcetree/sourcetreeitem.cpp index c9ec16101..c45bacddf 100644 --- a/src/sourcetree/sourcetreeitem.cpp +++ b/src/sourcetree/sourcetreeitem.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -46,14 +46,9 @@ SourceTreeItem::SourceTreeItem( const source_ptr& source, QObject* parent ) QString name; if( source.isNull() ) name = tr( "Super Collection" ); - else - { - if( TomahawkApp::instance()->scrubFriendlyName() && source->friendlyName().contains( '@' ) ) - name = source->friendlyName().left( source->friendlyName().indexOf( '@' ) ); - else - name = source->friendlyName(); - } - + else + name = source->friendlyName(); + QStandardItem* item = new QStandardItem( name ); item->setIcon( QIcon( RESPATH "images/user-avatar.png" ) ); item->setEditable( false ); @@ -114,7 +109,7 @@ SourceTreeItem::onPlaylistsAdded( const QList& playlists ) { // const-ness is important for getting the right pointer! foreach( const playlist_ptr& p, playlists ) - { + { m_playlists.append( p ); qlonglong ptr = reinterpret_cast( &m_playlists.last() ); diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 6693bd106..9ae0d8591 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -540,7 +540,7 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co QString tracks; int figWidth = 0; - if ( status ) + if ( status && sti && !sti->source().isNull() ) { tracks = QString::number( sti->source()->trackCount() ); figWidth = painter->fontMetrics().width( tracks ); diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 77c33ab96..194e5be73 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -150,7 +150,6 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] ) , m_sipHandler( 0 ) , m_servent( 0 ) , m_shortcutHandler( 0 ) - , m_scrubFriendlyName( false ) , m_mainwindow( 0 ) { qDebug() << "TomahawkApp thread:" << this->thread(); @@ -193,7 +192,6 @@ TomahawkApp::init() qDebug() << "Init Echonest Factory."; GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); - m_scrubFriendlyName = arguments().contains( "--demo" ); // Register shortcut handler for this platform #ifdef Q_WS_MAC m_shortcutHandler = new MacShortcutHandler( this ); From af9d2d388c8ad95d019cb5b11f1bc8bfd9852ee9 Mon Sep 17 00:00:00 2001 From: Alejandro Wainzinger Date: Wed, 20 Apr 2011 12:58:59 -0400 Subject: [PATCH 22/29] Lower the amount of time PortFwdThread waits until destruction. Greatly reduces shutdown time in the case where it can't communicate properly. --- src/libtomahawk/network/portfwdthread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/network/portfwdthread.cpp b/src/libtomahawk/network/portfwdthread.cpp index 36cdd8088..b2af82f17 100644 --- a/src/libtomahawk/network/portfwdthread.cpp +++ b/src/libtomahawk/network/portfwdthread.cpp @@ -41,7 +41,7 @@ PortFwdThread::~PortFwdThread() { qDebug() << Q_FUNC_INFO << "waiting for event loop to finish..."; quit(); - wait( 10000 ); + wait( 1000 ); delete m_portfwd; } From def3e3d868ff532366ee6879a4b01fd9aa847cb5 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 20 Apr 2011 20:22:06 +0200 Subject: [PATCH 23/29] Move SipHandler from application to library --- src/CMakeLists.txt | 3 - src/libtomahawk/CMakeLists.txt | 2 + src/{ => libtomahawk}/sip/SipHandler.cpp | 71 +++++++++++++++++++++++- src/{ => libtomahawk}/sip/SipHandler.h | 16 +++++- 4 files changed, 84 insertions(+), 8 deletions(-) rename src/{ => libtomahawk}/sip/SipHandler.cpp (83%) rename src/{ => libtomahawk}/sip/SipHandler.h (85%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 067558b19..1c3f3a8e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,8 +32,6 @@ ENDIF() #ENDFOREACH( moddir ) SET( tomahawkSources ${tomahawkSources} - sip/SipHandler.cpp - web/api_v1.cpp resolvers/scriptresolver.cpp @@ -71,7 +69,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} SET( tomahawkHeaders ${tomahawkHeaders} "${TOMAHAWK_INC_DIR}/tomahawk/tomahawkapp.h" - sip/SipHandler.h web/api_v1.h diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 33aaff411..01a18a12a 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -29,6 +29,7 @@ set( libSources viewpage.cpp sip/SipPlugin.cpp + sip/SipHandler.cpp audio/madtranscode.cpp audio/dummytranscode.cpp @@ -187,6 +188,7 @@ set( libHeaders playlist.h sip/SipPlugin.h + sip/SipHandler.h audio/transcodeinterface.h audio/madtranscode.h diff --git a/src/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp similarity index 83% rename from src/sip/SipHandler.cpp rename to src/libtomahawk/sip/SipHandler.cpp index 59aa8ea12..0170bdf64 100644 --- a/src/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -24,19 +24,33 @@ #include #include +#include "functimeout.h" + #include "database/database.h" #include "network/controlconnection.h" #include "sourcelist.h" #include "tomahawksettings.h" -#include "tomahawk/tomahawkapp.h" +//#include "tomahawk/tomahawkapp.h" #include "config.h" +//remove +#include + +SipHandler* SipHandler::s_instance = 0; + +SipHandler* SipHandler::instance() +{ + return s_instance; +} + SipHandler::SipHandler( QObject* parent ) : QObject( parent ) , m_connected( false ) { + s_instance = this; + loadPlugins( findPlugins() ); connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) ); @@ -55,6 +69,23 @@ SipHandler::plugins() const return m_plugins; } +const QPixmap SipHandler::avatar( const QString& name ) const +{ + qDebug() << Q_FUNC_INFO << "Getting avatar" << name << m_usernameAvatars.keys(); + if( m_usernameAvatars.keys().contains( name ) ) + { + qDebug() << Q_FUNC_INFO << "Getting avatar and avatar != null "; + Q_ASSERT(!m_usernameAvatars.value( name ).isNull()); + return m_usernameAvatars.value( name ); + } + else + { + qDebug() << Q_FUNC_INFO << "Getting avatar and avatar == null, GAAAAAH "; + return QPixmap(); + } +} + + void SipHandler::onSettingsChanged() @@ -147,6 +178,7 @@ SipHandler::loadPlugin( const QString& path ) QObject::connect( sip, SIGNAL( disconnected() ), SIGNAL( disconnected() ) ); QObject::connect( sip, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) ); + QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) ); m_plugins << sip; } } @@ -182,7 +214,8 @@ SipHandler::connectPlugins( bool startup, const QString &pluginName ) if ( !TomahawkSettings::instance()->acceptedLegalWarning() ) { int result = QMessageBox::question( - TomahawkApp::instance()->mainWindow(), tr( "Legal Warning" ), + //TomahawkApp::instance()->mainWindow(), + 0, tr( "Legal Warning" ), tr( "By pressing OK below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemnify the Tomahawk developers and project from liability should you choose to break those laws.\n\nFor more information, please see http://gettomahawk.com/legal" ), tr( "I Do Not Agree" ), tr( "I Agree" ) ); @@ -346,3 +379,35 @@ SipHandler::onError( int code, const QString& msg ) QTimer::singleShot( 10000, sip, SLOT( connectPlugin() ) ); } } + +void SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar ) +{ + qDebug() << Q_FUNC_INFO << "Set avatar on source for " << from; + Q_ASSERT(!avatar.isNull()); + + m_usernameAvatars.insert( from, avatar ); + + // + + //Tomahawk::source_ptr source = ->source(); + ControlConnection *conn = Servent::instance()->lookupControlConnection( from ); + if( conn ) + { + qDebug() << Q_FUNC_INFO << from << "got control connection"; + Tomahawk::source_ptr source = conn->source(); + if( source ) + { + + qDebug() << Q_FUNC_INFO << from << "got source, setting avatar"; + source->setAvatar( avatar ); + } + else + { + qDebug() << Q_FUNC_INFO << from << "no source found, not setting avatar"; + } + } + else + { + qDebug() << Q_FUNC_INFO << from << "no control connection setup yet"; + } +} diff --git a/src/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h similarity index 85% rename from src/sip/SipHandler.h rename to src/libtomahawk/sip/SipHandler.h index 0d3dcfa63..d394ea5d1 100644 --- a/src/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -23,19 +23,24 @@ #include #include +#include +#include +#include class SipHandler : public QObject { Q_OBJECT public: -// static SipHandler* instance() { return s_instance ? s_instance : new SipHandler(); } + static SipHandler* instance(); SipHandler( QObject* parent ); ~SipHandler(); QList< SipPlugin* > plugins() const; + const QPixmap avatar( const QString& name ) const; + public slots: void addContact( const QString& id ) { qDebug() << Q_FUNC_INFO << id; } @@ -57,7 +62,11 @@ private slots: void onSettingsChanged(); + void onAvatarReceived( const QString& from, const QPixmap& avatar = QPixmap()); + private: + static SipHandler *s_instance; + QStringList findPlugins(); bool pluginLoaded( const QString& name ) const; @@ -66,6 +75,9 @@ private: QList< SipPlugin* > m_plugins; bool m_connected; + + + QHash m_usernameAvatars; }; #endif From 47fd7b82859ce812c8744ba173d0e721ceb07bea Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 20 Apr 2011 20:30:04 +0200 Subject: [PATCH 24/29] Add avatar support to controlconnection, source and sourcetreeview. --- src/libtomahawk/network/controlconnection.cpp | 5 +++++ src/libtomahawk/network/controlconnection.h | 2 ++ src/libtomahawk/sip/SipPlugin.h | 4 +++- src/libtomahawk/source.cpp | 10 ++++++++++ src/libtomahawk/source.h | 4 ++++ src/sourcetree/sourcetreeview.cpp | 7 +++++-- 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/network/controlconnection.cpp b/src/libtomahawk/network/controlconnection.cpp index b1c7a0b50..1982ee8d7 100644 --- a/src/libtomahawk/network/controlconnection.cpp +++ b/src/libtomahawk/network/controlconnection.cpp @@ -23,6 +23,7 @@ #include "database/databasecommand_collectionstats.h" #include "dbsyncconnection.h" #include "sourcelist.h" +#include #define TCP_TIMEOUT 600 @@ -120,6 +121,10 @@ ControlConnection::registerSource() Source* source = (Source*) sender(); Q_UNUSED( source ) Q_ASSERT( source == m_source.data() ); + + qDebug() << Q_FUNC_INFO << "Setting avatar ... " << name() << !SipHandler::instance()->avatar( name() ).isNull(); + source->setAvatar( SipHandler::instance()->avatar( name() ) ); + // .. but we'll use the shared pointer we've already made: m_registered = true; diff --git a/src/libtomahawk/network/controlconnection.h b/src/libtomahawk/network/controlconnection.h index d23c91f43..f0f2b105b 100644 --- a/src/libtomahawk/network/controlconnection.h +++ b/src/libtomahawk/network/controlconnection.h @@ -44,6 +44,8 @@ public: DBSyncConnection* dbSyncConnection(); + Tomahawk::source_ptr source() const { return m_source; } + protected: virtual void setup(); diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 47af2fcf3..28e19ffb2 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -57,7 +57,9 @@ signals: void peerOnline( const QString& ); void peerOffline( const QString& ); void msgReceived( const QString& from, const QString& msg ); - + + void avatarReceived ( const QString& from, const QPixmap& avatar); + void addMenu( QMenu* menu ); void removeMenu( QMenu* menu ); }; diff --git a/src/libtomahawk/source.cpp b/src/libtomahawk/source.cpp index d825a7724..3e729d8f8 100644 --- a/src/libtomahawk/source.cpp +++ b/src/libtomahawk/source.cpp @@ -107,6 +107,16 @@ Source::friendlyName() const return m_friendlyname; } +void Source::setAvatar(const QPixmap& avatar) +{ + m_avatar = avatar; +} + +const QPixmap Source::avatar() const +{ + return m_avatar; +} + void Source::addCollection( const collection_ptr& c ) diff --git a/src/libtomahawk/source.h b/src/libtomahawk/source.h index ed48dfd1b..51d2dcdc7 100644 --- a/src/libtomahawk/source.h +++ b/src/libtomahawk/source.h @@ -54,6 +54,8 @@ public: QString userName() const { return m_username; } QString friendlyName() const; void setFriendlyName( const QString& fname ) { m_friendlyname = fname; } + void setAvatar(const QPixmap &avatar); + const QPixmap avatar() const; collection_ptr collection() const; void addCollection( const Tomahawk::collection_ptr& c ); @@ -116,6 +118,8 @@ private: QString m_textStatus; ControlConnection* m_cc; + + QPixmap m_avatar; }; }; diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 6693bd106..716d2cd18 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -537,17 +537,20 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co SourceTreeItem* sti = SourcesModel::indexToTreeItem( index ); bool status = !( !sti || sti->source().isNull() || !sti->source()->isOnline() ); + QPixmap avatar( RESPATH "images/user-avatar.png" ); QString tracks; int figWidth = 0; - if ( status ) + if ( status && sti && !sti->source().isNull() ) { tracks = QString::number( sti->source()->trackCount() ); figWidth = painter->fontMetrics().width( tracks ); + if ( !sti->source()->avatar().isNull() ) + avatar = sti->source()->avatar(); } QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 ); - painter->drawPixmap( iconRect, QPixmap( RESPATH "images/user-avatar.png" ).scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) ); + painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) ); if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) { From ddb7e012df29295b56233208ae99ba2968880721 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 20 Apr 2011 21:12:04 +0200 Subject: [PATCH 25/29] sipjreen: Add AvatarManager class --- src/sip/jreen/CMakeLists.txt | 2 + src/sip/jreen/avatarmanager.cpp | 171 ++++++++++++++++++++++++++++++++ src/sip/jreen/avatarmanager.h | 43 ++++++++ 3 files changed, 216 insertions(+) create mode 100644 src/sip/jreen/avatarmanager.cpp create mode 100644 src/sip/jreen/avatarmanager.h diff --git a/src/sip/jreen/CMakeLists.txt b/src/sip/jreen/CMakeLists.txt index 7cf3d3dd2..e0aa1b0d0 100644 --- a/src/sip/jreen/CMakeLists.txt +++ b/src/sip/jreen/CMakeLists.txt @@ -11,6 +11,7 @@ set( jabberSources jabber_p.cpp tomahawksipmessage.cpp tomahawksipmessagefactory.cpp + avatarmanager.cpp ) set( jabberHeaders @@ -18,6 +19,7 @@ set( jabberHeaders jabber_p.h tomahawksipmessage.h tomahawksipmessagefactory.h + avatarmanager.h ) include_directories( . ${CMAKE_CURRENT_BINARY_DIR} .. diff --git a/src/sip/jreen/avatarmanager.cpp b/src/sip/jreen/avatarmanager.cpp new file mode 100644 index 000000000..366d805e1 --- /dev/null +++ b/src/sip/jreen/avatarmanager.cpp @@ -0,0 +1,171 @@ +#include "avatarmanager.h" + + +#include "utils/tomahawkutils.h" + +#include +#include +#include + +#include +#include +#include +#include + +AvatarManager::AvatarManager(Jreen::Client *client) : + m_cacheDir(TomahawkUtils::appDataDir().absolutePath().append("/jreen/")) +{ + m_client = client; + + m_cachedAvatars = m_cacheDir.entryList(); + + connect(m_client, SIGNAL(serverFeaturesReceived(QSet)), SLOT(onNewConnection())); + connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence))); + connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ))); + + connect(this, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString))); +} + +AvatarManager::~AvatarManager() +{ +} + +void AvatarManager::onNewConnection() +{ + fetchVCard( m_client->jid().bare() ); +} + + +void AvatarManager::fetchVCard(const QString &jid) +{ + qDebug() << Q_FUNC_INFO; + + Jreen::IQ iq(Jreen::IQ::Get, jid ); + iq.addExtension(new Jreen::VCard()); + m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), 0 ); +} + +void AvatarManager::onNewPresence(const Jreen::Presence& presence) +{ + Jreen::VCardUpdate::Ptr update = presence.findExtension(); + if(update) + { + qDebug() << "vcard: found update for " << presence.from().full(); + if(!isCached(update->photoHash())) + { + qDebug() << presence.from().full() << "vcard: photo not cached, starting request..." << update->photoHash(); + fetchVCard( presence.from().bare() ); + } + else + { + qDebug() << presence.from().full() << "vcard: photo already cached no request necessary " << update->photoHash(); + m_JidsAvatarHashes.insert( update->photoHash(), presence.from().bare() ); + + Q_ASSERT(!this->avatar(presence.from().bare()).isNull()); + emit newAvatar(presence.from().bare()); + } + } + else + { + qDebug() << Q_FUNC_INFO << presence.from().full() << "got no statusupdateextension"; + + //TODO: do we want this? might fetch avatars for broken clients + fetchVCard( presence.from().bare() ); + } +} + +void AvatarManager::onNewIq(const Jreen::IQ& iq, int context) +{ + Jreen::VCard *vcard = iq.findExtension().data(); + if(vcard) + { + iq.accept(); + + qDebug() << Q_FUNC_INFO << "Got vcard from " << iq.from().full(); + + QString id = iq.from().full(); + QString avatarHash; + + const Jreen::VCard::Photo &photo = vcard->photo(); + if (!photo.data().isEmpty()) { + qDebug() << "vcard: got photo data" << id; + + avatarHash = QCryptographicHash::hash(photo.data(), QCryptographicHash::Sha1).toHex(); + + if (!m_cacheDir.exists()) + m_cacheDir.mkpath( avatarDir( avatarHash ).absolutePath() ); + + + QFile file(avatarPath(avatarHash)); + if (file.open(QIODevice::WriteOnly)) { + file.write(photo.data()); + file.close(); + } + + m_cachedAvatars.append(avatarHash); + m_JidsAvatarHashes.insert( avatarHash, iq.from().bare() ); + + Q_ASSERT(!this->avatar(iq.from().bare()).isNull()); + emit newAvatar(iq.from().bare()); + } + else + { + qDebug() << "vcard: got no photo data" << id; + } + + // got own presence + if ( m_client->jid().bare() == id ) + { + qDebug() << Q_FUNC_INFO << "got own vcard"; + + Jreen::Presence presence = m_client->presence(); + Jreen::VCardUpdate::Ptr update = presence.findExtension(); + if (update->photoHash() != avatarHash) + { + qDebug() << Q_FUNC_INFO << "Updating own presence..."; + + update->setPhotoHash(avatarHash); + m_client->send(presence); + } + } + } +} + +QPixmap AvatarManager::avatar(const QString &jid) const +{ + if( isCached( avatarHash( jid ) ) ) + { + return QPixmap( avatarPath( avatarHash( jid ) ) ); + } + else + { + return QPixmap(); + } +} + +QString AvatarManager::avatarHash(const QString &jid) const +{ + //qDebug() << Q_FUNC_INFO << jid << m_JidsAvatarHashes.key(jid); + return m_JidsAvatarHashes.key(jid); +} + +QDir AvatarManager::avatarDir(const QString &avatarHash) const +{ + return m_cacheDir; +} + +QString AvatarManager::avatarPath(const QString &avatarHash) const +{ + Q_ASSERT(!avatarHash.contains("@")); + return avatarDir(avatarHash).absoluteFilePath(avatarHash); +} + +bool AvatarManager::isCached(const QString &avatarHash) const +{ + return m_cachedAvatars.contains( avatarHash ); +} + +void AvatarManager::onNewAvatar(const QString& jid) +{ + qDebug() << Q_FUNC_INFO << "Found new Avatar..." << jid; +} diff --git a/src/sip/jreen/avatarmanager.h b/src/sip/jreen/avatarmanager.h new file mode 100644 index 000000000..71852285c --- /dev/null +++ b/src/sip/jreen/avatarmanager.h @@ -0,0 +1,43 @@ +#ifndef AVATARMANAGER_H +#define AVATARMANAGER_H + +#include + +#include +#include + + +class AvatarManager : public QObject +{ +Q_OBJECT + +public: + AvatarManager(Jreen::Client *client); + virtual ~AvatarManager(); + + QPixmap avatar(const QString &jid) const; + +signals: + void newAvatar( const QString &jid ); + +private slots: + void onNewPresence( const Jreen::Presence& presence ); + void onNewIq(const Jreen::IQ &iq, int context = 0 ); + void onNewConnection(); + void onNewAvatar( const QString &jid ); + +private: + void fetchVCard( const QString &jid); + QString avatarHash(const QString &jid) const; + QString avatarPath(const QString &avatarHash) const; + + QDir avatarDir(const QString &avatarHash) const; + bool isCached(const QString &avatarHash) const; + + Jreen::Client *m_client; + QStringList m_cachedAvatars; + QDir m_cacheDir; + QMap m_JidsAvatarHashes; +}; + +#endif // AVATARMANAGER_H From d9a4b71414c86264d3ca8639f5ebf104b09b9c32 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 20 Apr 2011 21:26:16 +0200 Subject: [PATCH 26/29] Use the AvatarManager and show avatars in the MainWindow. --- src/sip/jreen/jabber.cpp | 1 + src/sip/jreen/jabber_p.cpp | 42 ++++++++++++++++++++++++-------------- src/sip/jreen/jabber_p.h | 9 ++++---- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/sip/jreen/jabber.cpp b/src/sip/jreen/jabber.cpp index a4b0f1aab..e6982857b 100644 --- a/src/sip/jreen/jabber.cpp +++ b/src/sip/jreen/jabber.cpp @@ -110,6 +110,7 @@ JabberPlugin::connectPlugin( bool startup ) QObject::connect( p, SIGNAL( disconnected() ), SLOT( onDisconnected() ) ); QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) ); + QObject::connect( p, SIGNAL( avatarReceived( QString, QPixmap ) ), SIGNAL( avatarReceived( QString, QPixmap ) ) ); return true; } diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index 93efa5a06..ea5add54a 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -70,8 +70,8 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& // add VCardUpdate extension to own presence m_client->presence().addExtension( new Jreen::VCardUpdate() ); - // read cached avatars - m_photoHashes = QDir("/home/domme/jreen/").entryList(); + // initialize the AvatarManager + m_avatarManager = new AvatarManager(m_client); // setup disco m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM ); @@ -96,6 +96,8 @@ Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence))); connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ))); + connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString))); + // connect qDebug() << "Connecting to the XMPP server..."; @@ -226,9 +228,6 @@ Jabber_p::onConnect() // set presence to least valid value m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127); - // request own vcard - fetchVCard( m_jid.bare() ); - // set ping timeout to 15 secs (TODO: verify if this works) m_client->setPingInterval(15000); @@ -351,16 +350,6 @@ void Jabber_p::onNewPresence( const Jreen::Presence& presence) qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype(); - Jreen::VCardUpdate::Ptr update = presence.findExtension(); - if(update) - { - qDebug() << "vcard: found update for " << fulljid; - if(!m_photoHashes.contains(update->photoHash())) - { - fetchVCard( jid.bare() ); - } - } - if( jid == m_jid ) return; @@ -536,10 +525,33 @@ Jabber_p::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenc { m_peers[ fulljid ] = presenceType; qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid; + emit peerOnline( fulljid ); + + if(!m_avatarManager->avatar(jid.bare()).isNull()) + onNewAvatar( jid.bare() ); + return; } //qDebug() << "Updating presence data for" << fulljid; m_peers[ fulljid ] = presenceType; } + +void Jabber_p::onNewAvatar(const QString& jid) +{ + qDebug() << Q_FUNC_INFO << jid; + Q_ASSERT(!m_avatarManager->avatar( jid ).isNull()); + + // find peers for the jid + QStringList peers = m_peers.keys(); + foreach(const QString &peer, peers) + { + if( peer.startsWith(jid) ) + { + emit avatarReceived ( peer, m_avatarManager->avatar( jid ) ); + } + } + + emit avatarReceived ( jid, m_avatarManager->avatar( jid ) ); +} diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index 0fd354467..2d138b788 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -22,6 +22,8 @@ #include "../sipdllmacro.h" +#include "avatarmanager.h" + #include #include #include @@ -63,6 +65,7 @@ signals: void connected(); void disconnected(); void jidChanged( const QString& ); + void avatarReceived( const QString&, const QPixmap& avatar ); void authError( int, const QString& ); public slots: @@ -82,6 +85,7 @@ private slots: qDebug() << e; } virtual void onNewIq( const Jreen::IQ &iq, int context = NoContext ); + virtual void onNewAvatar( const QString &jid ); private: bool presenceMeansOnline( Jreen::Presence::Type p ); @@ -99,10 +103,7 @@ private: QStringList m_legacy_peers; - - //sort out - //QHash m_contactsPhotoHashes; - QStringList m_photoHashes; + AvatarManager *m_avatarManager; }; #endif // JABBER_H From 84019e5d115a480ba33217f414fc41b892a137bd Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 20 Apr 2011 21:43:14 +0200 Subject: [PATCH 27/29] Add DLLEXPORT macro to SipHandler --- src/libtomahawk/sip/SipHandler.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index d394ea5d1..cbef72f5d 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -20,6 +20,7 @@ #define SIPHANDLER_H #include "sip/SipPlugin.h" +#include "dllmacro.h" #include #include @@ -27,7 +28,7 @@ #include #include -class SipHandler : public QObject +class DLLEXPORT SipHandler : public QObject { Q_OBJECT From 3182a294d7749b79f0d8722bc5af28d0c5575a07 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 20 Apr 2011 23:30:44 +0200 Subject: [PATCH 28/29] Do not truncate FLAC playback. If "finish" is set, play until the buffer is empty. --- src/libtomahawk/audio/flactranscode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libtomahawk/audio/flactranscode.cpp b/src/libtomahawk/audio/flactranscode.cpp index c66c5a557..22f339c49 100644 --- a/src/libtomahawk/audio/flactranscode.cpp +++ b/src/libtomahawk/audio/flactranscode.cpp @@ -70,7 +70,7 @@ FLACTranscode::processData( const QByteArray& data, bool finish ) m_buffer.append( data ); m_mutex.unlock(); - while ( m_buffer.size() >= FLAC_BUFFER ) + while ( m_buffer.size() >= FLAC_BUFFER || ( finish && !m_buffer.isEmpty() ) ) { process_single(); } From 3e20fd1f6a3e6bec4fdffb050d2112176e7306ed Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 21 Apr 2011 13:42:16 +0200 Subject: [PATCH 29/29] Let SipHandler set the avatar for MyCollection --- src/libtomahawk/sip/SipHandler.cpp | 7 +++++++ src/libtomahawk/sip/SipHandler.h | 7 ++++++- src/libtomahawk/sip/SipPlugin.h | 5 +++++ src/sip/jreen/jabber.cpp | 1 + src/sip/jreen/jabber_p.cpp | 7 ++++++- src/sip/jreen/jabber_p.h | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/libtomahawk/sip/SipHandler.cpp b/src/libtomahawk/sip/SipHandler.cpp index 0170bdf64..a3b7b0375 100644 --- a/src/libtomahawk/sip/SipHandler.cpp +++ b/src/libtomahawk/sip/SipHandler.cpp @@ -179,6 +179,7 @@ SipHandler::loadPlugin( const QString& path ) QObject::connect( sip, SIGNAL( error( int, QString ) ), SLOT( onError( int, QString ) ) ); QObject::connect( sip, SIGNAL( avatarReceived( QString, QPixmap ) ), SLOT( onAvatarReceived( QString, QPixmap ) ) ); + QObject::connect( sip, SIGNAL( avatarReceived( QPixmap ) ), SLOT( onAvatarReceived( QPixmap ) ) ); m_plugins << sip; } } @@ -411,3 +412,9 @@ void SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar ) qDebug() << Q_FUNC_INFO << from << "no control connection setup yet"; } } + +void SipHandler::onAvatarReceived( const QPixmap& avatar ) +{ + qDebug() << Q_FUNC_INFO << "Set own avatar on MyCollection"; + SourceList::instance()->getLocal()->setAvatar( avatar ); +} diff --git a/src/libtomahawk/sip/SipHandler.h b/src/libtomahawk/sip/SipHandler.h index cbef72f5d..1c1c6f5bc 100644 --- a/src/libtomahawk/sip/SipHandler.h +++ b/src/libtomahawk/sip/SipHandler.h @@ -63,7 +63,12 @@ private slots: void onSettingsChanged(); - void onAvatarReceived( const QString& from, const QPixmap& avatar = QPixmap()); + // set data for local source + void onAvatarReceived( const QPixmap& avatar ); + + // set data for other sources + void onAvatarReceived( const QString& from, const QPixmap& avatar ); + private: static SipHandler *s_instance; diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index 28e19ffb2..4bd55fc31 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -58,8 +58,13 @@ signals: void peerOffline( const QString& ); void msgReceived( const QString& from, const QString& msg ); + // new data for own source + void avatarReceived ( const QPixmap& avatar ); + + // new data for other sources; void avatarReceived ( const QString& from, const QPixmap& avatar); + void addMenu( QMenu* menu ); void removeMenu( QMenu* menu ); }; diff --git a/src/sip/jreen/jabber.cpp b/src/sip/jreen/jabber.cpp index e6982857b..7e0b1235e 100644 --- a/src/sip/jreen/jabber.cpp +++ b/src/sip/jreen/jabber.cpp @@ -111,6 +111,7 @@ JabberPlugin::connectPlugin( bool startup ) QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) ); QObject::connect( p, SIGNAL( avatarReceived( QString, QPixmap ) ), SIGNAL( avatarReceived( QString, QPixmap ) ) ); + QObject::connect( p, SIGNAL( avatarReceived( QPixmap ) ), SIGNAL( avatarReceived( QPixmap) ) ); return true; } diff --git a/src/sip/jreen/jabber_p.cpp b/src/sip/jreen/jabber_p.cpp index ea5add54a..100ae908c 100644 --- a/src/sip/jreen/jabber_p.cpp +++ b/src/sip/jreen/jabber_p.cpp @@ -553,5 +553,10 @@ void Jabber_p::onNewAvatar(const QString& jid) } } - emit avatarReceived ( jid, m_avatarManager->avatar( jid ) ); + if( jid == m_client->jid().bare() ) + // own avatar + emit avatarReceived ( m_avatarManager->avatar( jid ) ); + else + // someone else's avatar + emit avatarReceived ( jid, m_avatarManager->avatar( jid ) ); } diff --git a/src/sip/jreen/jabber_p.h b/src/sip/jreen/jabber_p.h index 2d138b788..243e255a9 100644 --- a/src/sip/jreen/jabber_p.h +++ b/src/sip/jreen/jabber_p.h @@ -65,6 +65,7 @@ signals: void connected(); void disconnected(); void jidChanged( const QString& ); + void avatarReceived( const QPixmap& avatar ); void avatarReceived( const QString&, const QPixmap& avatar ); void authError( int, const QString& );