From 596794da57da05465e3f84071cf922575f199312 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Thu, 13 Mar 2014 02:15:13 +0000 Subject: [PATCH] Move IOFactories out of Servent --- src/libtomahawk-playdarapi/Api_v1.cpp | 3 +- src/libtomahawk/CMakeLists.txt | 1 + src/libtomahawk/UrlHandler.cpp | 130 ++++++++++++++++++ src/libtomahawk/UrlHandler.h | 50 +++++++ src/libtomahawk/UrlHandler_p.h | 56 ++++++++ src/libtomahawk/audio/AudioEngine.cpp | 3 +- src/libtomahawk/network/Servent.cpp | 95 +------------ src/libtomahawk/network/Servent.h | 14 +- src/libtomahawk/network/Servent_p.h | 1 - src/libtomahawk/network/StreamConnection.cpp | 3 +- .../resolvers/JSResolverHelper.cpp | 3 +- 11 files changed, 253 insertions(+), 106 deletions(-) create mode 100644 src/libtomahawk/UrlHandler.cpp create mode 100644 src/libtomahawk/UrlHandler.h create mode 100644 src/libtomahawk/UrlHandler_p.h diff --git a/src/libtomahawk-playdarapi/Api_v1.cpp b/src/libtomahawk-playdarapi/Api_v1.cpp index 89442003b..0df0aa895 100644 --- a/src/libtomahawk-playdarapi/Api_v1.cpp +++ b/src/libtomahawk-playdarapi/Api_v1.cpp @@ -32,6 +32,7 @@ #include "Pipeline.h" #include "Result.h" #include "Source.h" +#include "UrlHandler.h" #include @@ -243,7 +244,7 @@ Api_v1::sid( QxtWebRequestEvent* event, QString unused ) boost::function< void ( QSharedPointer< QIODevice >& ) > callback = boost::bind( &Api_v1::processSid, this, event, rp, _1 ); - Servent::instance()->getIODeviceForUrl( rp, callback ); + Tomahawk::UrlHandler::getIODeviceForUrl( rp, callback ); } diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index d94dfbbc0..784a7d671 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -209,6 +209,7 @@ list(APPEND libSources TrackData.cpp SourcePlaylistInterface.cpp PlaylistInterface.cpp + UrlHandler.cpp EchonestCatalogSynchronizer.cpp diff --git a/src/libtomahawk/UrlHandler.cpp b/src/libtomahawk/UrlHandler.cpp new file mode 100644 index 000000000..e705d5ef7 --- /dev/null +++ b/src/libtomahawk/UrlHandler.cpp @@ -0,0 +1,130 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac + * Copyright 2013-2014, Uwe L. Korn + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "UrlHandler_p.h" + +#include "utils/NetworkAccessManager.h" +#include "Result.h" + +#include + +#include + +Q_DECLARE_METATYPE( IODeviceCallback ) + +namespace Tomahawk { +namespace UrlHandler { + +QMap< QString, IODeviceFactoryFunc > iofactories; + +void +initialiseDefaultIOFactories() +{ + { + // _1 = result, _2 = callback function for IODevice + IODeviceFactoryFunc fac = boost::bind( localFileIODeviceFactory, _1, _2 ); + iofactories.insert( "file", fac ); + } + + { + IODeviceFactoryFunc fac = boost::bind( httpIODeviceFactory, _1, _2 ); + iofactories.insert( "http", fac ); + iofactories.insert( "https", fac ); + } + +} + +void +registerIODeviceFactory( const QString &proto, IODeviceFactoryFunc fac ) +{ + if ( iofactories.isEmpty() ) + { + initialiseDefaultIOFactories(); + } + + iofactories.insert( proto, fac ); +} + + +void +getIODeviceForUrl( const Tomahawk::result_ptr& result, + boost::function< void ( QSharedPointer< QIODevice >& ) > callback ) +{ + if ( iofactories.isEmpty() ) + { + initialiseDefaultIOFactories(); + } + + QSharedPointer sp; + + QRegExp rx( "^([a-zA-Z0-9]+)://(.+)$" ); + if ( rx.indexIn( result->url() ) == -1 ) + { + callback( sp ); + return; + } + + const QString proto = rx.cap( 1 ); + if ( !iofactories.contains( proto ) ) + { + callback( sp ); + return; + } + + // JSResolverHelper::customIODeviceFactory is async! + iofactories.value( proto )( result, callback ); +} + + +void +localFileIODeviceFactory( const Tomahawk::result_ptr& result, + boost::function< void ( QSharedPointer< QIODevice >& ) > callback ) +{ + // ignore "file://" at front of url + QFile* io = new QFile( result->url().mid( QString( "file://" ).length() ) ); + if ( io ) + io->open( QIODevice::ReadOnly ); + + //boost::functions cannot accept temporaries as parameters + QSharedPointer< QIODevice > sp = QSharedPointer( io ); + callback( sp ); +} + + +void +httpIODeviceFactory( const Tomahawk::result_ptr& result, + boost::function< void ( QSharedPointer< QIODevice >& ) > callback ) +{ + QNetworkRequest req( result->url() ); + // Follow HTTP Redirects + NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) ); + qRegisterMetaType("NetworkReply*"); + qRegisterMetaType("IODeviceCallback"); + HttpIODeviceReadyHandler* handler = new HttpIODeviceReadyHandler( reply, callback ); + reply->connect( reply, SIGNAL( finalUrlReached() ), + handler, SLOT( called() )); +} + + + + +} // namespace UrlHandler +} // namespace Tomahawk diff --git a/src/libtomahawk/UrlHandler.h b/src/libtomahawk/UrlHandler.h new file mode 100644 index 000000000..ba8a121b8 --- /dev/null +++ b/src/libtomahawk/UrlHandler.h @@ -0,0 +1,50 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2012, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac + * Copyright 2013-2014, Uwe L. Korn + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TOMAHAWK_URLHANDLER_H +#define TOMAHAWK_URLHANDLER_H + +#include "DllMacro.h" +#include "Typedefs.h" + +#include + +typedef boost::function< void( const Tomahawk::result_ptr&, + boost::function< void( QSharedPointer< QIODevice >& ) > )> IODeviceFactoryFunc; +typedef boost::function< void ( QSharedPointer< QIODevice >& ) > IODeviceCallback; + + +namespace Tomahawk +{ + +namespace UrlHandler +{ + + DLLEXPORT void getIODeviceForUrl( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); + DLLEXPORT void registerIODeviceFactory( const QString &proto, IODeviceFactoryFunc fac ); + DLLEXPORT void localFileIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); + DLLEXPORT void httpIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); + +} // namespace UrlHandler + +} // namespace Tomahawk + +#endif // TOMAHAWK_URLHANDLER_H diff --git a/src/libtomahawk/UrlHandler_p.h b/src/libtomahawk/UrlHandler_p.h new file mode 100644 index 000000000..3ad226e53 --- /dev/null +++ b/src/libtomahawk/UrlHandler_p.h @@ -0,0 +1,56 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2014, Uwe L. Korn + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef URLHANDLER_P_H +#define URLHANDLER_P_H + +#include "UrlHandler.h" + +#include "utils/NetworkReply.h" + +class HttpIODeviceReadyHandler : public QObject +{ + Q_OBJECT + +public: + + NetworkReply* reply; + IODeviceCallback callback; + QWeakPointer ref; + + HttpIODeviceReadyHandler( NetworkReply* _reply, IODeviceCallback _callback ) + : reply( _reply ) + , callback( _callback ) + { + // Do Nothing + } + +public slots: + + void called() + { + QSharedPointer< QIODevice > sp = QSharedPointer< QIODevice >( reply->reply(), &QObject::deleteLater ); + callback( sp ); + + // Call once, then self-destruct + deleteLater(); + } + +}; + +#endif // URLHANDLER_P_H diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index 1042a0339..b6124f098 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -37,6 +37,7 @@ #include "Pipeline.h" #include "PlaylistEntry.h" #include "TomahawkSettings.h" +#include "UrlHandler.h" #include @@ -632,7 +633,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) { boost::function< void ( QSharedPointer< QIODevice >& ) > callback = boost::bind( &AudioEngine::performLoadTrack, this, result, _1 ); - Servent::instance()->getIODeviceForUrl( d->currentTrack, callback ); + Tomahawk::UrlHandler::getIODeviceForUrl( d->currentTrack, callback ); } else { diff --git a/src/libtomahawk/network/Servent.cpp b/src/libtomahawk/network/Servent.cpp index 492b88b91..2125e9601 100644 --- a/src/libtomahawk/network/Servent.cpp +++ b/src/libtomahawk/network/Servent.cpp @@ -3,7 +3,7 @@ * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2012, Jeff Mitchell * Copyright 2013, Teo Mrnjavac - * Copyright 2013, Uwe L. Korn + * Copyright 2013-2014, Uwe L. Korn * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ #include "Source.h" #include "SourceList.h" #include "StreamConnection.h" +#include "UrlHandler.h" #include #include @@ -63,7 +64,7 @@ Q_DECLARE_METATYPE( QList< SipInfo > ) Q_DECLARE_METATYPE( Connection* ) Q_DECLARE_METATYPE( QTcpSocketExtra* ) Q_DECLARE_METATYPE( Tomahawk::peerinfo_ptr ) -Q_DECLARE_METATYPE( IODeviceCallback ) + using namespace Tomahawk; @@ -87,22 +88,8 @@ Servent::Servent( QObject* parent ) setProxy( QNetworkProxy::NoProxy ); - { - // _1 = result, _2 = callback function for IODevice - IODeviceFactoryFunc fac = boost::bind( &Servent::localFileIODeviceFactory, this, _1, _2 ); - this->registerIODeviceFactory( "file", fac ); - } - - { - IODeviceFactoryFunc fac = boost::bind( &Servent::remoteIODeviceFactory, this, _1, _2 ); - this->registerIODeviceFactory( "servent", fac ); - } - - { - IODeviceFactoryFunc fac = boost::bind( &Servent::httpIODeviceFactory, this, _1, _2 ); - this->registerIODeviceFactory( "http", fac ); - this->registerIODeviceFactory( "https", fac ); - } + IODeviceFactoryFunc fac = boost::bind( &Servent::remoteIODeviceFactory, this, _1, _2 ); + Tomahawk::UrlHandler::registerIODeviceFactory( "servent", fac ); } @@ -1381,78 +1368,6 @@ Servent::triggerDBSync() } -void -Servent::registerIODeviceFactory( const QString &proto, - IODeviceFactoryFunc fac ) -{ - d_func()->iofactories.insert( proto, fac ); -} - - -void -Servent::getIODeviceForUrl( const Tomahawk::result_ptr& result, - boost::function< void ( QSharedPointer< QIODevice >& ) > callback ) -{ - QSharedPointer sp; - - QRegExp rx( "^([a-zA-Z0-9]+)://(.+)$" ); - if ( rx.indexIn( result->url() ) == -1 ) - { - callback( sp ); - return; - } - - const QString proto = rx.cap( 1 ); - if ( !d_func()->iofactories.contains( proto ) ) - { - callback( sp ); - return; - } - - //JSResolverHelper::customIODeviceFactory is async! - d_func()->iofactories.value( proto )( result, callback ); -} - - -void -Servent::localFileIODeviceFactory( const Tomahawk::result_ptr& result, - boost::function< void ( QSharedPointer< QIODevice >& ) > callback ) -{ - // ignore "file://" at front of url - QFile* io = new QFile( result->url().mid( QString( "file://" ).length() ) ); - if ( io ) - io->open( QIODevice::ReadOnly ); - - //boost::functions cannot accept temporaries as parameters - QSharedPointer< QIODevice > sp = QSharedPointer( io ); - callback( sp ); -} - - -void -Servent::httpIODeviceFactory( const Tomahawk::result_ptr& result, - boost::function< void ( QSharedPointer< QIODevice >& ) > callback ) -{ - QNetworkRequest req( result->url() ); - // Follow HTTP Redirects - NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) ); - qRegisterMetaType("NetworkReply*"); - qRegisterMetaType("IODeviceCallback"); - NewClosure( reply, SIGNAL( finalUrlReached() ), - this, SLOT( httpIODeviceReady( NetworkReply*, IODeviceCallback ) ), - reply, callback )->setAutoDelete( true ); -} - - -void -Servent::httpIODeviceReady( NetworkReply* reply, IODeviceCallback callback ) -{ - //boost::functions cannot accept temporaries as parameters - QSharedPointer< QIODevice > sp = QSharedPointer< QIODevice >( reply->reply(), &QObject::deleteLater ); - callback( sp ); -} - - bool Servent::isReady() const { diff --git a/src/libtomahawk/network/Servent.h b/src/libtomahawk/network/Servent.h index cf7845d50..130c821ff 100644 --- a/src/libtomahawk/network/Servent.h +++ b/src/libtomahawk/network/Servent.h @@ -50,10 +50,6 @@ namespace boost template class function; } // boost -typedef boost::function< void( const Tomahawk::result_ptr&, - boost::function< void( QSharedPointer< QIODevice >& ) > )> IODeviceFactoryFunc; -typedef boost::function< void ( QSharedPointer< QIODevice >& ) > IODeviceCallback; - class ServentPrivate; class DLLEXPORT Servent : public QTcpServer @@ -81,6 +77,9 @@ public: ControlConnection* lookupControlConnection( const SipInfo& sipInfo ); ControlConnection* lookupControlConnection( const QString& nodeid ); + void remoteIODeviceFactory( const Tomahawk::result_ptr& result, + boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); + // you may call this method as often as you like for the same peerInfo, dupe checking is done inside void registerPeer( const Tomahawk::peerinfo_ptr& peerInfo ); void handleSipInfo( const Tomahawk::peerinfo_ptr& peerInfo ); @@ -124,12 +123,6 @@ public: QList< StreamConnection* > streams() const; - void getIODeviceForUrl( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); - void registerIODeviceFactory( const QString &proto, IODeviceFactoryFunc fac ); - void remoteIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); - void localFileIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); - void httpIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback ); - bool isReady() const; QList getLocalSipInfos(const QString& nodeid, const QString &key); @@ -168,7 +161,6 @@ public slots: void triggerDBSync(); void onSipInfoChanged(); - void httpIODeviceReady( NetworkReply* reply, IODeviceCallback callback ); private slots: void deleteLazyOffer( const QString& key ); diff --git a/src/libtomahawk/network/Servent_p.h b/src/libtomahawk/network/Servent_p.h index f8d809bfd..57a4409b8 100644 --- a/src/libtomahawk/network/Servent_p.h +++ b/src/libtomahawk/network/Servent_p.h @@ -48,7 +48,6 @@ public: Q_DECLARE_PUBLIC ( Servent ) private: - QMap< QString, IODeviceFactoryFunc > iofactories; QMap< QString, QPointer< Connection > > offers; QMap< QString, QPair< Tomahawk::peerinfo_ptr, QString > > lazyoffers; QStringList connectedNodes; diff --git a/src/libtomahawk/network/StreamConnection.cpp b/src/libtomahawk/network/StreamConnection.cpp index 7d58ec36d..6dbc8fcdb 100644 --- a/src/libtomahawk/network/StreamConnection.cpp +++ b/src/libtomahawk/network/StreamConnection.cpp @@ -31,6 +31,7 @@ #include "MsgProcessor.h" #include "Result.h" #include "SourceList.h" +#include "UrlHandler.h" #include #include @@ -189,7 +190,7 @@ StreamConnection::startSending( const Tomahawk::result_ptr& result ) boost::function< void ( QSharedPointer< QIODevice >& ) > callback = boost::bind( &StreamConnection::reallyStartSending, this, result, _1 ); - Servent::instance()->getIODeviceForUrl( m_result, callback ); + Tomahawk::UrlHandler::getIODeviceForUrl( m_result, callback ); } diff --git a/src/libtomahawk/resolvers/JSResolverHelper.cpp b/src/libtomahawk/resolvers/JSResolverHelper.cpp index 11e39c86d..4e3782f8c 100644 --- a/src/libtomahawk/resolvers/JSResolverHelper.cpp +++ b/src/libtomahawk/resolvers/JSResolverHelper.cpp @@ -36,6 +36,7 @@ #include "Pipeline.h" #include "Result.h" #include "SourceList.h" +#include "UrlHandler.h" #include #include @@ -455,7 +456,7 @@ JSResolverHelper::addCustomUrlHandler( const QString& protocol, boost::function< void( const Tomahawk::result_ptr&, boost::function< void( QSharedPointer< QIODevice >& ) > )> fac = boost::bind( &JSResolverHelper::customIODeviceFactory, this, _1, _2 ); - Servent::instance()->registerIODeviceFactory( protocol, fac ); + Tomahawk::UrlHandler::registerIODeviceFactory( protocol, fac ); m_urlCallback = callbackFuncName; }