mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-01 20:00:13 +02:00
* Added TransferView to monitor current streaming activity.
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
class ControlConnection;
|
class ControlConnection;
|
||||||
|
class FileTransferConnection;
|
||||||
|
|
||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
{
|
{
|
||||||
@@ -71,8 +72,10 @@ private:
|
|||||||
QString m_username, m_friendlyname;
|
QString m_username, m_friendlyname;
|
||||||
unsigned int m_id;
|
unsigned int m_id;
|
||||||
QList< QSharedPointer<Collection> > m_collections;
|
QList< QSharedPointer<Collection> > m_collections;
|
||||||
ControlConnection* m_cc;
|
|
||||||
QVariantMap m_stats;
|
QVariantMap m_stats;
|
||||||
|
|
||||||
|
ControlConnection* m_cc;
|
||||||
|
FileTransferConnection* m_ftc;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -140,6 +140,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
|
|||||||
|
|
||||||
infowidgets/sourceinfowidget.cpp
|
infowidgets/sourceinfowidget.cpp
|
||||||
|
|
||||||
|
transferview.cpp
|
||||||
tomahawkwindow.cpp
|
tomahawkwindow.cpp
|
||||||
tomahawktrayicon.cpp
|
tomahawktrayicon.cpp
|
||||||
audiocontrols.cpp
|
audiocontrols.cpp
|
||||||
@@ -270,6 +271,7 @@ SET( tomahawkHeadersGui ${tomahawkHeadersGui}
|
|||||||
|
|
||||||
infowidgets/sourceinfowidget.h
|
infowidgets/sourceinfowidget.h
|
||||||
|
|
||||||
|
transferview.h
|
||||||
tomahawkwindow.h
|
tomahawkwindow.h
|
||||||
tomahawktrayicon.h
|
tomahawktrayicon.h
|
||||||
audiocontrols.h
|
audiocontrols.h
|
||||||
@@ -321,12 +323,6 @@ ENDIF( WIN32 )
|
|||||||
IF( UNIX )
|
IF( UNIX )
|
||||||
INCLUDE( "CMakeLists.unix.txt" )
|
INCLUDE( "CMakeLists.unix.txt" )
|
||||||
ENDIF( UNIX )
|
ENDIF( UNIX )
|
||||||
IF( APPLE )
|
|
||||||
INCLUDE( "CMakeLists.osx.txt" )
|
|
||||||
ENDIF( APPLE )
|
|
||||||
IF( UNIX AND NOT APPLE )
|
|
||||||
INCLUDE( "CMakeLists.linux.txt" )
|
|
||||||
ENDIF( UNIX AND NOT APPLE )
|
|
||||||
|
|
||||||
kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/tomahawk-icon-*.png" )
|
kde4_add_app_icon( tomahawkSources "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/tomahawk-icon-*.png" )
|
||||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||||
|
@@ -19,3 +19,10 @@ SET( OS_SPECIFIC_LINK_LIBRARIES
|
|||||||
ogg
|
ogg
|
||||||
FLAC++
|
FLAC++
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF( APPLE )
|
||||||
|
INCLUDE( "CMakeLists.osx.txt" )
|
||||||
|
ENDIF( APPLE )
|
||||||
|
IF( UNIX AND NOT APPLE )
|
||||||
|
INCLUDE( "CMakeLists.linux.txt" )
|
||||||
|
ENDIF( UNIX AND NOT APPLE )
|
||||||
|
@@ -90,7 +90,7 @@ void
|
|||||||
ControlConnection::registerSource()
|
ControlConnection::registerSource()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
Source * source = (Source*) sender();
|
Source* source = (Source*) sender();
|
||||||
Q_ASSERT( source == m_source.data() );
|
Q_ASSERT( source == m_source.data() );
|
||||||
// .. but we'll use the shared pointer we've already made:
|
// .. but we'll use the shared pointer we've already made:
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ ControlConnection::registerSource()
|
|||||||
|
|
||||||
m_registered = true;
|
m_registered = true;
|
||||||
setupDbSyncConnection();
|
setupDbSyncConnection();
|
||||||
m_servent->registerControlConnection(this);
|
m_servent->registerControlConnection( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ ControlConnection::handleMsg( msg_ptr msg )
|
|||||||
{
|
{
|
||||||
if ( msg->is( Msg::PING ) )
|
if ( msg->is( Msg::PING ) )
|
||||||
{
|
{
|
||||||
qDebug() << "Received Connection PING, nice." << m_pingtimer_mark.elapsed();
|
// qDebug() << "Received Connection PING, nice." << m_pingtimer_mark.elapsed();
|
||||||
m_pingtimer_mark.restart();
|
m_pingtimer_mark.restart();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -46,8 +46,9 @@ FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FileTransferConnection::FileTransferConnection( Servent* s, QString fid )
|
FileTransferConnection::FileTransferConnection( Servent* s, ControlConnection* cc, QString fid )
|
||||||
: Connection( s )
|
: Connection( s )
|
||||||
|
, m_cc( cc )
|
||||||
, m_fid( fid )
|
, m_fid( fid )
|
||||||
, m_type( SENDING )
|
, m_type( SENDING )
|
||||||
, m_badded( 0 )
|
, m_badded( 0 )
|
||||||
@@ -74,7 +75,7 @@ FileTransferConnection::~FileTransferConnection()
|
|||||||
((BufferIODevice*)m_iodev.data())->inputComplete();
|
((BufferIODevice*)m_iodev.data())->inputComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
APP->servent().fileTransferFinished( this );
|
APP->servent().onFileTransferFinished( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -96,12 +97,29 @@ FileTransferConnection::showStats( qint64 tx, qint64 rx )
|
|||||||
<< QString( "Down: %L1 bytes/sec," ).arg( rx )
|
<< QString( "Down: %L1 bytes/sec," ).arg( rx )
|
||||||
<< QString( "Up: %L1 bytes/sec" ).arg( tx );
|
<< QString( "Up: %L1 bytes/sec" ).arg( tx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_transferRate = tx + rx;
|
||||||
|
emit updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FileTransferConnection::setup()
|
FileTransferConnection::setup()
|
||||||
{
|
{
|
||||||
|
QList<source_ptr> sources = APP->sourcelist().sources();
|
||||||
|
foreach( const source_ptr& src, sources )
|
||||||
|
{
|
||||||
|
// local src doesnt have a control connection, skip it:
|
||||||
|
if( src.isNull() || src->isLocal() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( src->controlConnection() == m_cc )
|
||||||
|
{
|
||||||
|
m_source = src;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
connect( this, SIGNAL( statsTick( qint64, qint64 ) ), SLOT( showStats( qint64, qint64 ) ) );
|
connect( this, SIGNAL( statsTick( qint64, qint64 ) ), SLOT( showStats( qint64, qint64 ) ) );
|
||||||
if( m_type == RECEIVING )
|
if( m_type == RECEIVING )
|
||||||
{
|
{
|
||||||
@@ -118,17 +136,19 @@ FileTransferConnection::setup()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FileTransferConnection::startSending( QVariantMap f )
|
FileTransferConnection::startSending( const QVariantMap& f )
|
||||||
{
|
{
|
||||||
Tomahawk::result_ptr result( new Tomahawk::Result( f, collection_ptr() ) );
|
m_result = Tomahawk::result_ptr( new Tomahawk::Result( f, collection_ptr() ) );
|
||||||
qDebug() << "Starting to transmit" << result->url();
|
qDebug() << "Starting to transmit" << m_result->url();
|
||||||
QSharedPointer<QIODevice> io = TomahawkApp::instance()->getIODeviceForUrl( result );
|
|
||||||
|
QSharedPointer<QIODevice> io = TomahawkApp::instance()->getIODeviceForUrl( m_result );
|
||||||
if( !io )
|
if( !io )
|
||||||
{
|
{
|
||||||
qDebug() << "Couldn't read from source:" << result->url();
|
qDebug() << "Couldn't read from source:" << m_result->url();
|
||||||
shutdown();
|
shutdown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_readdev = QSharedPointer<QIODevice>( io );
|
m_readdev = QSharedPointer<QIODevice>( io );
|
||||||
sendSome();
|
sendSome();
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "tomahawk/result.h"
|
||||||
|
|
||||||
class ControlConnection;
|
class ControlConnection;
|
||||||
class BufferIODevice;
|
class BufferIODevice;
|
||||||
@@ -22,9 +23,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// RX:
|
// RX:
|
||||||
explicit FileTransferConnection( Servent* s, ControlConnection* parent, QString fid, unsigned int size );
|
explicit FileTransferConnection( Servent* s, ControlConnection* cc, QString fid, unsigned int size );
|
||||||
// TX:
|
// TX:
|
||||||
explicit FileTransferConnection( Servent* s, QString fid );
|
explicit FileTransferConnection( Servent* s, ControlConnection* cc, QString fid );
|
||||||
|
|
||||||
virtual ~FileTransferConnection();
|
virtual ~FileTransferConnection();
|
||||||
|
|
||||||
@@ -33,15 +34,23 @@ public:
|
|||||||
Connection* clone();
|
Connection* clone();
|
||||||
|
|
||||||
const QSharedPointer<QIODevice>& iodevice() { return m_iodev; }
|
const QSharedPointer<QIODevice>& iodevice() { return m_iodev; }
|
||||||
|
ControlConnection* controlConnection() const { return m_cc; }
|
||||||
|
|
||||||
|
Tomahawk::source_ptr source() const { return m_source; }
|
||||||
|
Tomahawk::result_ptr track() const { return m_result; }
|
||||||
|
qint64 transferRate() const { return m_transferRate; }
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
QString fid() const { return m_fid; }
|
QString fid() const { return m_fid; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void updated();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void handleMsg( msg_ptr msg );
|
virtual void handleMsg( msg_ptr msg );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startSending( QVariantMap );
|
void startSending( const QVariantMap& );
|
||||||
void sendSome();
|
void sendSome();
|
||||||
void showStats(qint64 tx, qint64 rx);
|
void showStats(qint64 tx, qint64 rx);
|
||||||
|
|
||||||
@@ -54,6 +63,10 @@ private:
|
|||||||
|
|
||||||
int m_badded, m_bsent;
|
int m_badded, m_bsent;
|
||||||
bool m_allok; // got last msg ok, transfer complete?
|
bool m_allok; // got last msg ok, transfer complete?
|
||||||
|
|
||||||
|
Tomahawk::source_ptr m_source;
|
||||||
|
Tomahawk::result_ptr m_result;
|
||||||
|
qint64 m_transferRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILETRANSFERCONNECTION_H
|
#endif // FILETRANSFERCONNECTION_H
|
||||||
|
@@ -121,9 +121,10 @@ QString
|
|||||||
Servent::createConnectionKey( const QString& name )
|
Servent::createConnectionKey( const QString& name )
|
||||||
{
|
{
|
||||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||||
|
|
||||||
QString key = uuid();
|
QString key = uuid();
|
||||||
ControlConnection * cc = new ControlConnection( this );
|
ControlConnection * cc = new ControlConnection( this );
|
||||||
cc->setName( name=="" ? QString( "KEY(%1)" ).arg(key) : name );
|
cc->setName( name.isEmpty() ? QString( "KEY(%1)" ).arg( key ) : name );
|
||||||
registerOffer( key, cc );
|
registerOffer( key, cc );
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@@ -227,37 +228,51 @@ Servent::readyRead()
|
|||||||
sock->_msg->fill( ba );
|
sock->_msg->fill( ba );
|
||||||
Q_ASSERT( sock->_msg->is( Msg::JSON ) );
|
Q_ASSERT( sock->_msg->is( Msg::JSON ) );
|
||||||
|
|
||||||
|
ControlConnection* cc = 0;
|
||||||
bool ok;
|
bool ok;
|
||||||
int pport = 0;
|
int pport = 0;
|
||||||
QString key, conntype, nodeid;
|
QString key, conntype, nodeid, controlid;
|
||||||
QVariantMap m = parser.parse( sock->_msg->payload(), &ok ).toMap();
|
QVariantMap m = parser.parse( sock->_msg->payload(), &ok ).toMap();
|
||||||
if( !ok )
|
if( !ok )
|
||||||
{
|
{
|
||||||
qDebug() << "Invalid JSON on new conection, aborting";
|
qDebug() << "Invalid JSON on new conection, aborting";
|
||||||
goto closeconnection;
|
goto closeconnection;
|
||||||
}
|
}
|
||||||
conntype = m.value( "conntype" ).toString();
|
conntype = m.value( "conntype" ).toString();
|
||||||
key = m.value( "key" ).toString();
|
key = m.value( "key" ).toString();
|
||||||
pport = m.value( "port" ).toInt();
|
pport = m.value( "port" ).toInt();
|
||||||
nodeid = m.value( "nodeid" ).toString();
|
nodeid = m.value( "nodeid" ).toString();
|
||||||
|
controlid = m.value( "controlid" ).toString();
|
||||||
|
|
||||||
qDebug() << m;
|
qDebug() << m;
|
||||||
|
|
||||||
if( !nodeid.isEmpty() ) // only control connections send nodeid
|
if( !nodeid.isEmpty() && cc != 0 ) // only control connections send nodeid
|
||||||
foreach( ControlConnection* cc, m_controlconnections )
|
|
||||||
{
|
{
|
||||||
if( cc->id() == nodeid )
|
foreach( ControlConnection* con, m_controlconnections )
|
||||||
{
|
{
|
||||||
qDebug() << "Duplicate control connection detected, dropping:" << nodeid << conntype;
|
qDebug() << con->socket() << sock;
|
||||||
goto closeconnection;
|
if( con->id() == nodeid )
|
||||||
|
{
|
||||||
|
qDebug() << "Duplicate control connection detected, dropping:" << nodeid << conntype;
|
||||||
|
goto closeconnection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach( ControlConnection* con, m_controlconnections )
|
||||||
|
{
|
||||||
|
qDebug() << "cons:" << con;
|
||||||
|
qDebug() << "conid:" << con->id();
|
||||||
|
|
||||||
|
if ( con->id() == controlid )
|
||||||
|
cc = con;
|
||||||
|
}
|
||||||
|
|
||||||
// they connected to us and want something we are offering
|
// they connected to us and want something we are offering
|
||||||
if( conntype == "accept-offer" || "push-offer" )
|
if( conntype == "accept-offer" || "push-offer" )
|
||||||
{
|
{
|
||||||
sock->_msg.clear();
|
sock->_msg.clear();
|
||||||
Connection * conn = claimOffer( key, sock->peerAddress() );
|
Connection* conn = claimOffer( cc, key, sock->peerAddress() );
|
||||||
if( !conn )
|
if( !conn )
|
||||||
{
|
{
|
||||||
qDebug() << "claimOffer FAILED, key:" << key;
|
qDebug() << "claimOffer FAILED, key:" << key;
|
||||||
@@ -265,10 +280,10 @@ Servent::readyRead()
|
|||||||
}
|
}
|
||||||
qDebug() << "claimOffer OK:" << key;
|
qDebug() << "claimOffer OK:" << key;
|
||||||
|
|
||||||
if( !nodeid.isEmpty() ) conn->setId( nodeid );
|
if( !nodeid.isEmpty() )
|
||||||
|
conn->setId( nodeid );
|
||||||
|
|
||||||
handoverSocket( conn, sock );
|
handoverSocket( conn, sock );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -310,6 +325,7 @@ Servent::createParallelConnection( Connection* orig_conn, Connection* new_conn,
|
|||||||
m.insert( "key", tmpkey );
|
m.insert( "key", tmpkey );
|
||||||
m.insert( "offer", key );
|
m.insert( "offer", key );
|
||||||
m.insert( "port", externalPort() );
|
m.insert( "port", externalPort() );
|
||||||
|
m.insert( "controlid", orig_conn->id() );
|
||||||
|
|
||||||
QJson::Serializer ser;
|
QJson::Serializer ser;
|
||||||
orig_conn->sendMsg( Msg::factory( ser.serialize(m), Msg::JSON ) );
|
orig_conn->sendMsg( Msg::factory( ser.serialize(m), Msg::JSON ) );
|
||||||
@@ -383,10 +399,10 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, const Q
|
|||||||
|
|
||||||
ControlConnection* conn = new ControlConnection( this );
|
ControlConnection* conn = new ControlConnection( this );
|
||||||
QVariantMap m;
|
QVariantMap m;
|
||||||
m["conntype"] = "accept-offer";
|
m["conntype"] = "accept-offer";
|
||||||
m["key"] = key;
|
m["key"] = key;
|
||||||
m["port"] = externalPort();
|
m["port"] = externalPort();
|
||||||
m["nodeid"] = APP->nodeID();
|
m["nodeid"] = APP->nodeID();
|
||||||
|
|
||||||
conn->setFirstMessage( m );
|
conn->setFirstMessage( m );
|
||||||
if( name.length() )
|
if( name.length() )
|
||||||
@@ -411,9 +427,10 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
|
|||||||
if( key.length() && conn->firstMessage().isNull() )
|
if( key.length() && conn->firstMessage().isNull() )
|
||||||
{
|
{
|
||||||
QVariantMap m;
|
QVariantMap m;
|
||||||
m["conntype"] = "accept-offer";
|
m["conntype"] = "accept-offer";
|
||||||
m["key"] = key;
|
m["key"] = key;
|
||||||
m["port"] = externalPort();
|
m["port"] = externalPort();
|
||||||
|
m["controlid"] = APP->nodeID();
|
||||||
conn->setFirstMessage( m );
|
conn->setFirstMessage( m );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,13 +452,13 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const QString& theirkey )
|
Servent::reverseOfferRequest( ControlConnection* orig_conn, const QString& key, const QString& theirkey )
|
||||||
{
|
{
|
||||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||||
|
|
||||||
qDebug() << "Servent::reverseOfferRequest received for" << key;
|
qDebug() << "Servent::reverseOfferRequest received for" << key;
|
||||||
Connection * new_conn = claimOffer( key );
|
Connection* new_conn = claimOffer( orig_conn, key );
|
||||||
if( !new_conn )
|
if ( !new_conn )
|
||||||
{
|
{
|
||||||
qDebug() << "claimOffer failed, killing requesting connection out of spite";
|
qDebug() << "claimOffer failed, killing requesting connection out of spite";
|
||||||
orig_conn->shutdown();
|
orig_conn->shutdown();
|
||||||
@@ -449,9 +466,10 @@ Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const Q
|
|||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap m;
|
QVariantMap m;
|
||||||
m["conntype"] = "push-offer";
|
m["conntype"] = "push-offer";
|
||||||
m["key"] = theirkey;
|
m["key"] = theirkey;
|
||||||
m["port"] = externalPort();
|
m["port"] = externalPort();
|
||||||
|
m["controlid"] = orig_conn->id();
|
||||||
new_conn->setFirstMessage( m );
|
new_conn->setFirstMessage( m );
|
||||||
createParallelConnection( orig_conn, new_conn, QString() );
|
createParallelConnection( orig_conn, new_conn, QString() );
|
||||||
}
|
}
|
||||||
@@ -459,12 +477,12 @@ Servent::reverseOfferRequest( Connection* orig_conn, const QString& key, const Q
|
|||||||
|
|
||||||
// return the appropriate connection for a given offer key, or NULL if invalid
|
// return the appropriate connection for a given offer key, or NULL if invalid
|
||||||
Connection*
|
Connection*
|
||||||
Servent::claimOffer( const QString &key, const QHostAddress peer )
|
Servent::claimOffer( ControlConnection* cc, const QString &key, const QHostAddress peer )
|
||||||
{
|
{
|
||||||
bool noauth = qApp->arguments().contains( "--noauth" );
|
bool noauth = qApp->arguments().contains( "--noauth" );
|
||||||
|
|
||||||
// magic key for file transfers:
|
// magic key for file transfers:
|
||||||
if( key.startsWith("FILE_REQUEST_KEY:") )
|
if( key.startsWith( "FILE_REQUEST_KEY:" ) )
|
||||||
{
|
{
|
||||||
// check if the source IP matches an existing, authenticated connection
|
// check if the source IP matches an existing, authenticated connection
|
||||||
if ( !noauth && peer != QHostAddress::Any && !isIPWhitelisted( peer ) )
|
if ( !noauth && peer != QHostAddress::Any && !isIPWhitelisted( peer ) )
|
||||||
@@ -486,13 +504,13 @@ Servent::claimOffer( const QString &key, const QHostAddress peer )
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString fid = key.right( key.length() - 17 );
|
QString fid = key.right( key.length() - 17 );
|
||||||
FileTransferConnection* ftc = new FileTransferConnection( this, fid );
|
FileTransferConnection* ftc = new FileTransferConnection( this, cc, fid );
|
||||||
return ftc;
|
return ftc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( key == "whitelist" ) // LAN IP address, check source IP
|
if( key == "whitelist" ) // LAN IP address, check source IP
|
||||||
{
|
{
|
||||||
if( isIPWhitelisted(peer) )
|
if( isIPWhitelisted( peer ) )
|
||||||
{
|
{
|
||||||
qDebug() << "Connection is from whitelisted IP range (LAN)";
|
qDebug() << "Connection is from whitelisted IP range (LAN)";
|
||||||
Connection* conn = new ControlConnection( this );
|
Connection* conn = new ControlConnection( this );
|
||||||
@@ -567,23 +585,28 @@ void
|
|||||||
Servent::registerFileTransferConnection( FileTransferConnection* ftc )
|
Servent::registerFileTransferConnection( FileTransferConnection* ftc )
|
||||||
{
|
{
|
||||||
Q_ASSERT( !m_ftsessions.contains( ftc ) );
|
Q_ASSERT( !m_ftsessions.contains( ftc ) );
|
||||||
QMutexLocker lock( &m_ftsession_mut );
|
|
||||||
qDebug() << "Registering FileTransfer" << m_ftsessions.length() + 1;
|
qDebug() << "Registering FileTransfer" << m_ftsessions.length() + 1;
|
||||||
|
|
||||||
|
QMutexLocker lock( &m_ftsession_mut );
|
||||||
m_ftsessions.append( ftc );
|
m_ftsessions.append( ftc );
|
||||||
|
|
||||||
printCurrentTransfers();
|
printCurrentTransfers();
|
||||||
|
emit fileTransferStarted( ftc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Servent::fileTransferFinished( FileTransferConnection* ftc )
|
Servent::onFileTransferFinished( FileTransferConnection* ftc )
|
||||||
{
|
{
|
||||||
Q_ASSERT( ftc );
|
Q_ASSERT( ftc );
|
||||||
|
|
||||||
qDebug() << "FileTransfer Finished, unregistering" << ftc->id();
|
qDebug() << "FileTransfer Finished, unregistering" << ftc->id();
|
||||||
|
|
||||||
QMutexLocker lock( &m_ftsession_mut );
|
QMutexLocker lock( &m_ftsession_mut );
|
||||||
int rem = m_ftsessions.removeAll( ftc );
|
int rem = m_ftsessions.removeAll( ftc );
|
||||||
Q_ASSERT( rem == 1 );
|
Q_ASSERT( rem == 1 );
|
||||||
|
|
||||||
printCurrentTransfers();
|
printCurrentTransfers();
|
||||||
|
emit fileTransferFinished( ftc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -608,11 +631,11 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
|||||||
static QList<range> whitelist;
|
static QList<range> whitelist;
|
||||||
if( whitelist.isEmpty() )
|
if( whitelist.isEmpty() )
|
||||||
{
|
{
|
||||||
whitelist << range( QHostAddress("10.0.0.0"), 8 )
|
whitelist << range( QHostAddress( "10.0.0.0" ), 8 )
|
||||||
<< range( QHostAddress("172.16.0.0"), 12 )
|
<< range( QHostAddress( "172.16.0.0" ), 12 )
|
||||||
<< range( QHostAddress("192.168.0.0"), 16 )
|
<< range( QHostAddress( "192.168.0.0" ), 16 )
|
||||||
<< range( QHostAddress("169.254.0.0"), 16 )
|
<< range( QHostAddress( "169.254.0.0" ), 16 )
|
||||||
<< range( QHostAddress("127.0.0.0"), 24 );
|
<< range( QHostAddress( "127.0.0.0" ), 24 );
|
||||||
|
|
||||||
// qDebug() << "Loaded whitelist IP range:" << whitelist;
|
// qDebug() << "Loaded whitelist IP range:" << whitelist;
|
||||||
}
|
}
|
||||||
|
@@ -82,7 +82,7 @@ public:
|
|||||||
|
|
||||||
void connectToPeer( const QString& ha, int port, const QString &key, const QString& name = "", const QString& id = "" );
|
void connectToPeer( const QString& ha, int port, const QString &key, const QString& name = "", const QString& id = "" );
|
||||||
void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn );
|
void connectToPeer( const QString& ha, int port, const QString &key, Connection* conn );
|
||||||
void reverseOfferRequest( Connection* orig_conn, const QString& key, const QString& theirkey );
|
void reverseOfferRequest( ControlConnection* orig_conn, const QString& key, const QString& theirkey );
|
||||||
|
|
||||||
void setExternalAddress( QHostAddress ha, int port );
|
void setExternalAddress( QHostAddress ha, int port );
|
||||||
bool visibleExternally() const { return m_externalPort > 0; }
|
bool visibleExternally() const { return m_externalPort > 0; }
|
||||||
@@ -93,9 +93,14 @@ public:
|
|||||||
static bool isIPWhitelisted( QHostAddress ip );
|
static bool isIPWhitelisted( QHostAddress ip );
|
||||||
|
|
||||||
bool connectedToSession( const QString& session );
|
bool connectedToSession( const QString& session );
|
||||||
|
|
||||||
unsigned int numConnectedPeers() const { return m_controlconnections.length(); }
|
unsigned int numConnectedPeers() const { return m_controlconnections.length(); }
|
||||||
|
|
||||||
|
QList< FileTransferConnection* > fileTransfers() const { return m_ftsessions; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void fileTransferStarted( FileTransferConnection* );
|
||||||
|
void fileTransferFinished( FileTransferConnection* );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void incomingConnection( int sd );
|
void incomingConnection( int sd );
|
||||||
|
|
||||||
@@ -104,7 +109,7 @@ public slots:
|
|||||||
void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
|
void createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key );
|
||||||
|
|
||||||
void registerFileTransferConnection( FileTransferConnection* );
|
void registerFileTransferConnection( FileTransferConnection* );
|
||||||
void fileTransferFinished( FileTransferConnection* ftc );
|
void onFileTransferFinished( FileTransferConnection* ftc );
|
||||||
|
|
||||||
void socketConnected();
|
void socketConnected();
|
||||||
void triggerDBSync();
|
void triggerDBSync();
|
||||||
@@ -112,7 +117,7 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void readyRead();
|
void readyRead();
|
||||||
|
|
||||||
Connection* claimOffer( const QString &key, const QHostAddress peer = QHostAddress::Any );
|
Connection* claimOffer( ControlConnection* cc, const QString &key, const QHostAddress peer = QHostAddress::Any );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handoverSocket( Connection* conn, QTcpSocketExtra* sock );
|
void handoverSocket( Connection* conn, QTcpSocketExtra* sock );
|
||||||
|
@@ -18,6 +18,7 @@ Source::Source( const QString &username, ControlConnection* cc )
|
|||||||
, m_username( username )
|
, m_username( username )
|
||||||
, m_id( 0 )
|
, m_id( 0 )
|
||||||
, m_cc( cc )
|
, m_cc( cc )
|
||||||
|
, m_ftc( 0 )
|
||||||
{
|
{
|
||||||
// source for local machine doesn't have a controlconnection. this is normal.
|
// source for local machine doesn't have a controlconnection. this is normal.
|
||||||
if ( cc )
|
if ( cc )
|
||||||
|
@@ -65,6 +65,9 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
|
|||||||
ui->splitter->setStretchFactor( 0, 1 );
|
ui->splitter->setStretchFactor( 0, 1 );
|
||||||
ui->splitter->setStretchFactor( 1, 3 );
|
ui->splitter->setStretchFactor( 1, 3 );
|
||||||
|
|
||||||
|
ui->splitter_2->setStretchFactor( 0, 3 );
|
||||||
|
ui->splitter_2->setStretchFactor( 1, 1 );
|
||||||
|
|
||||||
QToolBar* toolbar = addToolBar( "TomahawkToolbar" );
|
QToolBar* toolbar = addToolBar( "TomahawkToolbar" );
|
||||||
toolbar->setObjectName( "TomahawkToolbar" );
|
toolbar->setObjectName( "TomahawkToolbar" );
|
||||||
toolbar->addWidget( m_topbar );
|
toolbar->addWidget( m_topbar );
|
||||||
|
@@ -20,13 +20,19 @@
|
|||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="SourceTreeView" name="sourceTreeView">
|
<widget class="AnimatedSplitter" name="splitter_2">
|
||||||
<property name="minimumSize">
|
<property name="orientation">
|
||||||
<size>
|
<enum>Qt::Vertical</enum>
|
||||||
<width>250</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="SourceTreeView" name="sourceTreeView">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>250</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="TransferView" name="treeWidget"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="playlistWidget" native="true"/>
|
<widget class="QWidget" name="playlistWidget" native="true"/>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -144,6 +150,17 @@
|
|||||||
<extends>QTreeView</extends>
|
<extends>QTreeView</extends>
|
||||||
<header>sourcetreeview.h</header>
|
<header>sourcetreeview.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>AnimatedSplitter</class>
|
||||||
|
<extends>QSplitter</extends>
|
||||||
|
<header location="global">animatedsplitter.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TransferView</class>
|
||||||
|
<extends>QTreeWidget</extends>
|
||||||
|
<header>transferview.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
74
src/transferview.cpp
Normal file
74
src/transferview.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#include "transferview.h"
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
#include "tomahawk/tomahawkapp.h"
|
||||||
|
#include "network/filetransferconnection.h"
|
||||||
|
#include "network/servent.h"
|
||||||
|
|
||||||
|
|
||||||
|
TransferView::TransferView( QWidget* parent )
|
||||||
|
: QTreeWidget( parent )
|
||||||
|
{
|
||||||
|
connect( &APP->servent(), SIGNAL( fileTransferStarted( FileTransferConnection* ) ), SLOT( fileTransferRegistered( FileTransferConnection* ) ) );
|
||||||
|
connect( &APP->servent(), SIGNAL( fileTransferFinished( FileTransferConnection* ) ), SLOT( fileTransferFinished( FileTransferConnection* ) ) );
|
||||||
|
|
||||||
|
QStringList headers;
|
||||||
|
headers << tr( "Peer" ) << tr( "Rate" ) << tr( "Track" );
|
||||||
|
setHeaderLabels( headers );
|
||||||
|
|
||||||
|
setColumnCount( 3 );
|
||||||
|
setColumnWidth( 0, 80 );
|
||||||
|
setColumnWidth( 1, 65 );
|
||||||
|
setColumnWidth( 2, 10 );
|
||||||
|
|
||||||
|
header()->setStretchLastSection( true );
|
||||||
|
setRootIsDecorated( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TransferView::fileTransferRegistered( FileTransferConnection* ftc )
|
||||||
|
{
|
||||||
|
connect( ftc, SIGNAL( updated() ), SLOT( onTransferUpdate() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TransferView::fileTransferFinished( FileTransferConnection* ftc )
|
||||||
|
{
|
||||||
|
if ( !m_index.contains( ftc ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* int i = m_index.take( ftc );
|
||||||
|
delete invisibleRootItem()->takeChild( i ); */
|
||||||
|
|
||||||
|
if ( m_index.contains( ftc ) )
|
||||||
|
{
|
||||||
|
int i = m_index.value( ftc );
|
||||||
|
invisibleRootItem()->child( i )->setText( 1, tr( "Finished" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TransferView::onTransferUpdate()
|
||||||
|
{
|
||||||
|
FileTransferConnection* ftc = (FileTransferConnection*)sender();
|
||||||
|
QTreeWidgetItem* ti = 0;
|
||||||
|
|
||||||
|
if ( m_index.contains( ftc ) )
|
||||||
|
{
|
||||||
|
int i = m_index.value( ftc );
|
||||||
|
ti = invisibleRootItem()->child( i );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ti = new QTreeWidgetItem( this );
|
||||||
|
m_index.insert( ftc, invisibleRootItem()->childCount() - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
ti->setText( 0, ftc->source()->friendlyName() );
|
||||||
|
ti->setText( 1, QString( "%1 kb/s" ).arg( ftc->transferRate() / 1024 ) );
|
||||||
|
ti->setText( 2, QString( "%1 - %2" ).arg( ftc->track()->artist()->name() ).arg( ftc->track()->track() ) );
|
||||||
|
}
|
36
src/transferview.h
Normal file
36
src/transferview.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef TRANSFERVIEW_H
|
||||||
|
#define TRANSFERVIEW_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTreeWidget>
|
||||||
|
|
||||||
|
#include "tomahawk/typedefs.h"
|
||||||
|
|
||||||
|
class FileTransferConnection;
|
||||||
|
|
||||||
|
class TransferView : public QTreeWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TransferView( QWidget* parent = 0 );
|
||||||
|
virtual ~TransferView()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void fileTransferRegistered( FileTransferConnection* ftc );
|
||||||
|
void fileTransferFinished( FileTransferConnection* ftc );
|
||||||
|
|
||||||
|
void onTransferUpdate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash< FileTransferConnection*, int > m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TRANSFERVIEW_H
|
Reference in New Issue
Block a user