/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 295 lines · 225 code · 44 blank · 26 comment · 16 complexity · 4a48798c03bca5c4d237b8bab0dbeba7 MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. *
  5. * Tomahawk is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Tomahawk is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "echonestplugin.h"
  19. #include <echonest/Artist.h>
  20. #include <echonest/ArtistTypes.h>
  21. #include "utils/tomahawkutils.h"
  22. #include "utils/logger.h"
  23. #include <QNetworkConfiguration>
  24. using namespace Tomahawk::InfoSystem;
  25. using namespace Echonest;
  26. // for internal neatness
  27. EchoNestPlugin::EchoNestPlugin()
  28. : InfoPlugin()
  29. {
  30. qDebug() << Q_FUNC_INFO;
  31. m_supportedGetTypes << Tomahawk::InfoSystem::InfoArtistBiography << Tomahawk::InfoSystem::InfoArtistFamiliarity << Tomahawk::InfoSystem::InfoArtistHotttness << Tomahawk::InfoSystem::InfoArtistTerms << Tomahawk::InfoSystem::InfoMiscTopTerms;
  32. Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
  33. }
  34. EchoNestPlugin::~EchoNestPlugin()
  35. {
  36. qDebug() << Q_FUNC_INFO;
  37. }
  38. void
  39. EchoNestPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
  40. {
  41. switch ( requestData.type )
  42. {
  43. case Tomahawk::InfoSystem::InfoArtistBiography:
  44. return getArtistBiography( requestData );
  45. case Tomahawk::InfoSystem::InfoArtistFamiliarity:
  46. return getArtistFamiliarity( requestData );
  47. case Tomahawk::InfoSystem::InfoArtistHotttness:
  48. return getArtistHotttnesss( requestData );
  49. case Tomahawk::InfoSystem::InfoArtistTerms:
  50. return getArtistTerms( requestData );
  51. case Tomahawk::InfoSystem::InfoTrackEnergy:
  52. return getSongProfile( requestData, "energy" );
  53. case Tomahawk::InfoSystem::InfoMiscTopTerms:
  54. return getMiscTopTerms( requestData );
  55. default:
  56. {
  57. emit info( requestData, QVariant() );
  58. return;
  59. }
  60. }
  61. }
  62. void
  63. EchoNestPlugin::getSongProfile( const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item )
  64. {
  65. //WARNING: Totally not implemented yet
  66. Q_UNUSED( item );
  67. if( !isValidTrackData( requestData ) )
  68. return;
  69. // Track track( input.toString() );
  70. // Artist artist( customData.input()->property("artistName").toString() );
  71. // reply->setProperty("artist", QVariant::fromValue<Artist>(artist));
  72. // reply->setProperty( "input", input );
  73. // m_replyMap[reply] = customData;
  74. // connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot()));
  75. }
  76. void
  77. EchoNestPlugin::getArtistBiography( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  78. {
  79. if( !isValidArtistData( requestData ) )
  80. return;
  81. Echonest::Artist artist( requestData.input.toString() );
  82. QNetworkReply *reply = artist.fetchBiographies();
  83. reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
  84. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  85. connect( reply, SIGNAL( finished() ), SLOT( getArtistBiographySlot() ) );
  86. }
  87. void
  88. EchoNestPlugin::getArtistFamiliarity( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  89. {
  90. if( !isValidArtistData( requestData ) )
  91. return;
  92. qDebug() << "Fetching artist familiarity!" << requestData.input;
  93. Echonest::Artist artist( requestData.input.toString() );
  94. QNetworkReply* reply = artist.fetchFamiliarity();
  95. reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
  96. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  97. connect( reply, SIGNAL( finished() ), SLOT( getArtistFamiliaritySlot() ) );
  98. }
  99. void
  100. EchoNestPlugin::getArtistHotttnesss( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  101. {
  102. if( !isValidArtistData( requestData ) )
  103. return;
  104. Echonest::Artist artist( requestData.input.toString() );
  105. QNetworkReply* reply = artist.fetchHotttnesss();
  106. reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
  107. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  108. connect( reply, SIGNAL( finished() ), SLOT( getArtistHotttnesssSlot() ) );
  109. }
  110. void
  111. EchoNestPlugin::getArtistTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  112. {
  113. if( !isValidArtistData( requestData ) )
  114. return;
  115. Echonest::Artist artist( requestData.input.toString() );
  116. QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight );
  117. reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
  118. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  119. connect( reply, SIGNAL( finished() ), SLOT( getArtistTermsSlot() ) );
  120. }
  121. void
  122. EchoNestPlugin::getMiscTopTerms( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  123. {
  124. QNetworkReply* reply = Echonest::Artist::topTerms( 20 );
  125. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  126. connect( reply, SIGNAL( finished() ), SLOT( getMiscTopSlot() ) );
  127. }
  128. void
  129. EchoNestPlugin::getArtistBiographySlot()
  130. {
  131. QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
  132. Echonest::Artist artist = artistFromReply( reply );
  133. BiographyList biographies = artist.biographies();
  134. QVariantMap biographyMap;
  135. Q_FOREACH( const Biography& biography, biographies )
  136. {
  137. QVariantHash siteData;
  138. siteData[ "site" ] = biography.site();
  139. siteData[ "url" ] = biography.url().toString();
  140. siteData[ "text" ] = biography.text();
  141. siteData[ "attribution" ] = biography.license().attribution;
  142. siteData[ "licensetype" ] = biography.license().type;
  143. siteData[ "attribution" ] = biography.license().url.toString();
  144. biographyMap[ biography.site() ] = siteData;
  145. }
  146. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  147. emit info( requestData, biographyMap );
  148. reply->deleteLater();
  149. }
  150. void
  151. EchoNestPlugin::getArtistFamiliaritySlot()
  152. {
  153. QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
  154. Echonest::Artist artist = artistFromReply( reply );
  155. qreal familiarity = artist.familiarity();
  156. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  157. emit info( requestData, familiarity );
  158. reply->deleteLater();
  159. }
  160. void
  161. EchoNestPlugin::getArtistHotttnesssSlot()
  162. {
  163. QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
  164. Echonest::Artist artist = artistFromReply( reply );
  165. qreal hotttnesss = artist.hotttnesss();
  166. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  167. emit info( requestData, hotttnesss );
  168. reply->deleteLater();
  169. }
  170. void
  171. EchoNestPlugin::getArtistTermsSlot()
  172. {
  173. QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
  174. Echonest::Artist artist = artistFromReply( reply );
  175. TermList terms = artist.terms();
  176. QVariantMap termsMap;
  177. Q_FOREACH( const Echonest::Term& term, terms ) {
  178. QVariantHash termHash;
  179. termHash[ "weight" ] = QString::number( term.weight() );
  180. termHash[ "frequency" ] = QString::number( term.frequency() );
  181. termsMap[ term.name() ] = termHash;
  182. }
  183. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  184. emit info( requestData, termsMap );
  185. reply->deleteLater();
  186. }
  187. void
  188. EchoNestPlugin::getMiscTopSlot()
  189. {
  190. QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
  191. TermList terms = Echonest::Artist::parseTopTerms( reply );
  192. QVariantMap termsMap;
  193. Q_FOREACH( const Echonest::Term& term, terms ) {
  194. QVariantHash termHash;
  195. termHash[ "weight" ] = QString::number( term.weight() );
  196. termHash[ "frequency" ] = QString::number( term.frequency() );
  197. termsMap[ term.name() ] = termHash;
  198. }
  199. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  200. emit info( requestData, termsMap );
  201. reply->deleteLater();
  202. }
  203. bool
  204. EchoNestPlugin::isValidArtistData( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  205. {
  206. if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() )
  207. {
  208. emit info( requestData, QVariant() );
  209. return false;
  210. }
  211. QString artistName = requestData.input.toString();
  212. if ( artistName.isEmpty() )
  213. {
  214. emit info( requestData, QVariant() );
  215. return false;
  216. }
  217. return true;
  218. }
  219. bool
  220. EchoNestPlugin::isValidTrackData( const Tomahawk::InfoSystem::InfoRequestData &requestData )
  221. {
  222. if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() )
  223. {
  224. emit info( requestData, QVariant() );
  225. return false;
  226. }
  227. QString trackName = requestData.input.toString();
  228. if ( trackName.isEmpty() )
  229. {
  230. emit info( requestData, QVariant() );
  231. return false;
  232. }
  233. if ( !requestData.customData.contains( "artistName" ) || requestData.customData[ "artistName" ].toString().isEmpty() )
  234. {
  235. emit info( requestData, QVariant() );
  236. return false;
  237. }
  238. return true;
  239. }
  240. Artist
  241. EchoNestPlugin::artistFromReply( QNetworkReply* reply )
  242. {
  243. Echonest::Artist artist = reply->property("artist").value<Echonest::Artist>();
  244. try {
  245. artist.parseProfile( reply );
  246. } catch( const Echonest::ParseError& e ) {
  247. qWarning() << "Caught parser error from echonest!" << e.what();
  248. }
  249. return artist;
  250. }
  251. //