diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6349911ad..78aefef0d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -160,6 +160,7 @@ IF(GLOOX_FOUND) ENDIF(GLOOX_FOUND) ADD_SUBDIRECTORY( accounts ) +ADD_SUBDIRECTORY( infoplugins ) IF(QCA2_FOUND) INCLUDE_DIRECTORIES( ${QCA2_INCLUDE_DIR} ) diff --git a/src/infoplugins/CMakeLists.txt b/src/infoplugins/CMakeLists.txt new file mode 100644 index 000000000..ea6f39bf1 --- /dev/null +++ b/src/infoplugins/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY( generic ) diff --git a/src/infoplugins/InfoPluginDllMacro.h b/src/infoplugins/InfoPluginDllMacro.h new file mode 100644 index 000000000..0ae9b7db6 --- /dev/null +++ b/src/infoplugins/InfoPluginDllMacro.h @@ -0,0 +1,33 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2010-2011, Jeff Mitchell + * + * 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 INFOPLUGINDLLMACRO_H +#define INFOPLUGINDLLMACRO_H + +#include + +#ifndef INFOPLUGINDLLEXPORT +# if defined (INFOPLUGINDLLEXPORT_PRO) +# define INFOPLUGINDLLEXPORT Q_DECL_EXPORT +# else +# define INFOPLUGINDLLEXPORT Q_DECL_IMPORT +# endif +#endif + +#endif diff --git a/src/infoplugins/generic/CMakeLists.txt b/src/infoplugins/generic/CMakeLists.txt new file mode 100644 index 000000000..0a9ed2c32 --- /dev/null +++ b/src/infoplugins/generic/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY( echonest ) diff --git a/src/infoplugins/generic/echonest/CMakeLists.txt b/src/infoplugins/generic/echonest/CMakeLists.txt new file mode 100644 index 000000000..b956444f2 --- /dev/null +++ b/src/infoplugins/generic/echonest/CMakeLists.txt @@ -0,0 +1,45 @@ +project( tomahawk ) + +include( ${QT_USE_FILE} ) +add_definitions( ${QT_DEFINITIONS} ) +add_definitions( -DQT_PLUGIN ) +add_definitions( -DQT_SHARED ) +add_definitions( -DINFOPLUGINDLLEXPORT_PRO ) + +set( echonestInfoPluginSources + EchonestPlugin.cpp +) + +set( echonestInfoPluginHeaders + EchonestPlugin.h +) + +include_directories( + ${QT_INCLUDE_DIR} + ${LIBECHONEST_INCLUDE_DIR} +) + +qt4_wrap_cpp( echonestInfoPluginMoc ${echonestInfoPluginHeaders} ) +add_library( tomahawk_infoplugin_echonest SHARED ${echonestInfoPluginSources} ${echonestInfoPluginMoc} ${RC_SRCS} ) + +IF( WIN32 ) +SET( OS_SPECIFIC_LINK_LIBRARIES + ${OS_SPECIFIC_LINK_LIBRARIES} + "winmm.dll" + "iphlpapi.a" +) +ENDIF( WIN32 ) + +target_link_libraries( tomahawk_infoplugin_echonest + ${TOMAHAWK_LIBRARIES} + ${LIBECHONEST_LIBRARY} + ${QT_LIBRARIES} + ${OS_SPECIFIC_LINK_LIBRARIES} +) + +IF( APPLE ) +# SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" ) +ENDIF( APPLE ) + +install( TARGETS tomahawk_infoplugin_echonest DESTINATION ${CMAKE_INSTALL_LIBDIR} ) + diff --git a/src/libtomahawk/infosystem/infoplugins/generic/EchonestPlugin.cpp b/src/infoplugins/generic/echonest/EchonestPlugin.cpp similarity index 87% rename from src/libtomahawk/infosystem/infoplugins/generic/EchonestPlugin.cpp rename to src/infoplugins/generic/echonest/EchonestPlugin.cpp index 128bea70e..f1d28b89a 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/EchonestPlugin.cpp +++ b/src/infoplugins/generic/echonest/EchonestPlugin.cpp @@ -18,20 +18,23 @@ */ #include "EchonestPlugin.h" -#include #include #include "utils/TomahawkUtils.h" #include "utils/Logger.h" #include +#include -using namespace Tomahawk::InfoSystem; -using namespace Echonest; +namespace Tomahawk +{ + +namespace InfoSystem +{ // for internal neatness -EchoNestPlugin::EchoNestPlugin() +EchonestPlugin::EchonestPlugin() : InfoPlugin() { qDebug() << Q_FUNC_INFO; @@ -40,14 +43,14 @@ EchoNestPlugin::EchoNestPlugin() } -EchoNestPlugin::~EchoNestPlugin() +EchonestPlugin::~EchonestPlugin() { qDebug() << Q_FUNC_INFO; } void -EchoNestPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) +EchonestPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) { switch ( requestData.type ) { @@ -73,7 +76,7 @@ EchoNestPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) void -EchoNestPlugin::getSongProfile( const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item ) +EchonestPlugin::getSongProfile( const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item ) { //WARNING: Totally not implemented yet Q_UNUSED( item ); @@ -91,7 +94,7 @@ EchoNestPlugin::getSongProfile( const Tomahawk::InfoSystem::InfoRequestData &req void -EchoNestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { if( !isValidArtistData( requestData ) ) return; @@ -105,7 +108,7 @@ EchoNestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData void -EchoNestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { if( !isValidArtistData( requestData ) ) return; @@ -120,7 +123,7 @@ EchoNestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestDat void -EchoNestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { if( !isValidArtistData( requestData ) ) return; @@ -134,7 +137,7 @@ EchoNestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData void -EchoNestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { if( !isValidArtistData( requestData ) ) return; @@ -148,7 +151,7 @@ EchoNestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &req void -EchoNestPlugin::getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { QNetworkReply* reply = Echonest::Artist::topTerms( 20 ); reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); @@ -157,13 +160,13 @@ EchoNestPlugin::getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData &re void -EchoNestPlugin::getArtistBiographySlot() +EchonestPlugin::getArtistBiographySlot() { QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); - BiographyList biographies = artist.biographies(); + Echonest::BiographyList biographies = artist.biographies(); QVariantMap biographyMap; - Q_FOREACH( const Biography& biography, biographies ) + Q_FOREACH( const Echonest::Biography& biography, biographies ) { QVariantHash siteData; siteData[ "site" ] = biography.site(); @@ -181,7 +184,7 @@ EchoNestPlugin::getArtistBiographySlot() void -EchoNestPlugin::getArtistFamiliaritySlot() +EchonestPlugin::getArtistFamiliaritySlot() { QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); @@ -193,7 +196,7 @@ EchoNestPlugin::getArtistFamiliaritySlot() void -EchoNestPlugin::getArtistHotttnesssSlot() +EchonestPlugin::getArtistHotttnesssSlot() { QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); @@ -205,11 +208,11 @@ EchoNestPlugin::getArtistHotttnesssSlot() void -EchoNestPlugin::getArtistTermsSlot() +EchonestPlugin::getArtistTermsSlot() { QNetworkReply* reply = qobject_cast( sender() ); Echonest::Artist artist = artistFromReply( reply ); - TermList terms = artist.terms(); + Echonest::TermList terms = artist.terms(); QVariantMap termsMap; Q_FOREACH( const Echonest::Term& term, terms ) { QVariantHash termHash; @@ -224,10 +227,10 @@ EchoNestPlugin::getArtistTermsSlot() void -EchoNestPlugin::getMiscTopSlot() +EchonestPlugin::getMiscTopSlot() { QNetworkReply* reply = qobject_cast( sender() ); - TermList terms = Echonest::Artist::parseTopTerms( reply ); + Echonest::TermList terms = Echonest::Artist::parseTopTerms( reply ); QVariantMap termsMap; Q_FOREACH( const Echonest::Term& term, terms ) { QVariantHash termHash; @@ -242,7 +245,7 @@ EchoNestPlugin::getMiscTopSlot() bool -EchoNestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() ) { @@ -260,7 +263,7 @@ EchoNestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData & bool -EchoNestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &requestData ) +EchonestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &requestData ) { if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() ) { @@ -282,8 +285,8 @@ EchoNestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &r } -Artist -EchoNestPlugin::artistFromReply( QNetworkReply* reply ) +Echonest::Artist +EchonestPlugin::artistFromReply( QNetworkReply* reply ) { Echonest::Artist artist = reply->property("artist").value(); try { @@ -293,4 +296,9 @@ EchoNestPlugin::artistFromReply( QNetworkReply* reply ) } return artist; } -// + +} //ns InfoSystem + +} //ns Tomahawk + +Q_EXPORT_PLUGIN2( Tomahawk::InfoSystem::InfoPlugin, Tomahawk::InfoSystem::EchonestPlugin ) \ No newline at end of file diff --git a/src/libtomahawk/infosystem/infoplugins/generic/EchonestPlugin.h b/src/infoplugins/generic/echonest/EchonestPlugin.h similarity index 91% rename from src/libtomahawk/infosystem/infoplugins/generic/EchonestPlugin.h rename to src/infoplugins/generic/echonest/EchonestPlugin.h index 4497af432..4468c375c 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/EchonestPlugin.h +++ b/src/infoplugins/generic/echonest/EchonestPlugin.h @@ -20,31 +20,29 @@ #ifndef ECHONESTPLUGIN_H #define ECHONESTPLUGIN_H +#include "infoplugins/InfoPluginDllMacro.h" #include "infosystem/InfoSystem.h" #include "infosystem/InfoSystemWorker.h" +#include "echonest/Artist.h" #include class QNetworkReply; -namespace Echonest -{ - class Artist; -} - namespace Tomahawk { namespace InfoSystem { -class EchoNestPlugin : public InfoPlugin +class INFOPLUGINDLLEXPORT EchonestPlugin : public InfoPlugin { Q_OBJECT + Q_INTERFACES( Tomahawk::InfoSystem::InfoPlugin ) public: - EchoNestPlugin(); - virtual ~EchoNestPlugin(); + EchonestPlugin(); + virtual ~EchonestPlugin(); protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index afeed00ef..75290e04b 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -254,7 +254,6 @@ set( libSources infosystem/InfoSystemCache.cpp infosystem/InfoSystemWorker.cpp - infosystem/infoplugins/generic/EchonestPlugin.cpp infosystem/infoplugins/generic/ChartsPlugin.cpp infosystem/infoplugins/generic/NewReleasesPlugin.cpp infosystem/infoplugins/generic/spotifyPlugin.cpp diff --git a/src/libtomahawk/infosystem/InfoSystem.h b/src/libtomahawk/infosystem/InfoSystem.h index 1689e2bbb..2ec1429f4 100644 --- a/src/libtomahawk/infosystem/InfoSystem.h +++ b/src/libtomahawk/infosystem/InfoSystem.h @@ -336,7 +336,6 @@ inline uint qHash( Tomahawk::InfoSystem::InfoStringHash hash ) return returnval; } - Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoPushData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoStringHash ); @@ -348,4 +347,6 @@ Q_DECLARE_METATYPE( QList< Tomahawk::InfoSystem::InfoStringHash > ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoPluginPtr ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoPlugin* ); +Q_DECLARE_INTERFACE( Tomahawk::InfoSystem::InfoPlugin, "tomahawk.InfoPluginy/1.0" ) + #endif // TOMAHAWK_INFOSYSTEM_H diff --git a/src/libtomahawk/infosystem/InfoSystemWorker.cpp b/src/libtomahawk/infosystem/InfoSystemWorker.cpp index 803c607df..391f33a0a 100644 --- a/src/libtomahawk/infosystem/InfoSystemWorker.cpp +++ b/src/libtomahawk/infosystem/InfoSystemWorker.cpp @@ -21,11 +21,13 @@ #include #include #include +#include #include "config.h" +#include "HeadlessCheck.h" #include "InfoSystemWorker.h" #include "InfoSystemCache.h" -#include "infoplugins/generic/EchonestPlugin.h" +#include "infoplugins/generic/echonest/EchonestPlugin.h" #include "infoplugins/generic/MusixMatchPlugin.h" #include "infoplugins/generic/ChartsPlugin.h" #include "infoplugins/generic/NewReleasesPlugin.h" @@ -82,8 +84,11 @@ InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache ) tDebug() << Q_FUNC_INFO; m_shortLinksWaiting = 0; m_cache = cache; + + loadInfoPlugins( findInfoPlugins() ); + #ifndef ENABLE_HEADLESS - addInfoPlugin( InfoPluginPtr( new EchoNestPlugin() ) ); + //addInfoPlugin( InfoPluginPtr( new EchoNestPlugin() ) ); addInfoPlugin( InfoPluginPtr( new MusixMatchPlugin() ) ); addInfoPlugin( InfoPluginPtr( new MusicBrainzPlugin() ) ); addInfoPlugin( InfoPluginPtr( new ChartsPlugin() ) ); @@ -178,6 +183,83 @@ InfoSystemWorker::removeInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin ) } +QStringList +InfoSystemWorker::findInfoPlugins() +{ + QStringList paths; + QList< QDir > pluginDirs; + + QDir appDir( qApp->applicationDirPath() ); +#ifdef Q_WS_MAC + if ( appDir.dirName() == "MacOS" ) + { + // Development convenience-hack + appDir.cdUp(); + appDir.cdUp(); + appDir.cdUp(); + } +#endif + + QDir libDir( CMAKE_INSTALL_PREFIX "/lib" ); + + QDir lib64Dir( appDir ); + lib64Dir.cdUp(); + lib64Dir.cd( "lib64" ); + + pluginDirs << appDir << libDir << lib64Dir << QDir( qApp->applicationDirPath() ); + foreach ( const QDir& pluginDir, pluginDirs ) + { + tDebug() << Q_FUNC_INFO << "Checking directory for plugins:" << pluginDir; + foreach ( QString fileName, pluginDir.entryList( QStringList() << "*tomahawk_infoplugin_*.so" << "*tomahawk_infoplugin_*.dylib" << "*tomahawk_infoplugin_*.dll", QDir::Files ) ) + { + if ( fileName.startsWith( "libtomahawk_infoplugin" ) ) + { + const QString path = pluginDir.absoluteFilePath( fileName ); + if ( !paths.contains( path ) ) + paths << path; + } + } + } + + return paths; +} + + +void +InfoSystemWorker::loadInfoPlugins( const QStringList& pluginPaths ) +{ + tDebug() << Q_FUNC_INFO << "Attempting to load the following plugin paths: " << pluginPaths; + + if ( pluginPaths.isEmpty() ) + return; + + foreach ( const QString fileName, pluginPaths ) + { + if ( !QLibrary::isLibrary( fileName ) ) + continue; + + tDebug() << Q_FUNC_INFO << "Trying to load plugin:" << fileName; + + QPluginLoader loader( fileName ); + QObject* plugin = loader.instance(); + if ( !plugin ) + { + tDebug() << Q_FUNC_INFO << "Error loading plugin:" << loader.errorString(); + continue; + } + + InfoPlugin* infoPlugin = qobject_cast< InfoPlugin* >( plugin ); + if ( infoPlugin ) + { + tDebug() << Q_FUNC_INFO << "Loaded info plugin:" << loader.fileName(); + addInfoPlugin( InfoPluginPtr( infoPlugin ) ); + } + else + tDebug() << Q_FUNC_INFO << "Loaded invalid plugin: " << loader.fileName(); + } +} + + void InfoSystemWorker::registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType >& getTypes, const QSet< InfoType >& pushTypes ) { diff --git a/src/libtomahawk/infosystem/InfoSystemWorker.h b/src/libtomahawk/infosystem/InfoSystemWorker.h index f580ffd78..930f0d2e4 100644 --- a/src/libtomahawk/infosystem/InfoSystemWorker.h +++ b/src/libtomahawk/infosystem/InfoSystemWorker.h @@ -64,6 +64,8 @@ public slots: void addInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin ); void removeInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin ); + QStringList findInfoPlugins(); + void loadInfoPlugins( const QStringList &pluginPaths ); void getShortUrl( Tomahawk::InfoSystem::InfoPushData data ); void shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariant callbackObj ); diff --git a/src/libtomahawk/network/Servent.cpp b/src/libtomahawk/network/Servent.cpp index 8643263de..ec409f041 100644 --- a/src/libtomahawk/network/Servent.cpp +++ b/src/libtomahawk/network/Servent.cpp @@ -452,6 +452,14 @@ Servent::socketConnected() tDebug( LOGVERBOSE ) << Q_FUNC_INFO << thread() << "socket: " << sock << ", hostaddr: " << sock->peerAddress() << ", hostname: " << sock->peerName(); + if ( sock->_conn.isNull() ) + { + sock->close(); + sock->deleteLater(); + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Socket's connection was null, could have timed out or been given an invalid address"; + return; + } + Connection* conn = sock->_conn.data(); handoverSocket( conn, sock ); }