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

http://github.com/tomahawk-player/tomahawk · C++ · 328 lines · 255 code · 56 blank · 17 comment · 28 complexity · 8f259eadae4195102a53dc10a8c06541 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 "musicbrainzPlugin.h"
  19. #include <QNetworkReply>
  20. #include <QDomDocument>
  21. #include "utils/tomahawkutils.h"
  22. #include "utils/logger.h"
  23. using namespace Tomahawk::InfoSystem;
  24. MusicBrainzPlugin::MusicBrainzPlugin()
  25. : InfoPlugin()
  26. {
  27. qDebug() << Q_FUNC_INFO;
  28. m_supportedGetTypes << Tomahawk::InfoSystem::InfoArtistReleases << Tomahawk::InfoSystem::InfoAlbumSongs;
  29. }
  30. MusicBrainzPlugin::~MusicBrainzPlugin()
  31. {
  32. qDebug() << Q_FUNC_INFO;
  33. }
  34. void
  35. MusicBrainzPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
  36. {
  37. if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
  38. {
  39. emit info( requestData, QVariant() );
  40. return;
  41. }
  42. InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
  43. if ( !hash.contains( "artist" ) )
  44. {
  45. emit info( requestData, QVariant() );
  46. return;
  47. }
  48. switch ( requestData.type )
  49. {
  50. case InfoArtistReleases:
  51. {
  52. Tomahawk::InfoSystem::InfoStringHash criteria;
  53. criteria["artist"] = hash["artist"];
  54. emit getCachedInfo( criteria, 2419200000, requestData );
  55. break;
  56. }
  57. case InfoAlbumSongs:
  58. {
  59. Tomahawk::InfoSystem::InfoStringHash criteria;
  60. criteria["artist"] = hash["artist"];
  61. criteria["album"] = hash["album"];
  62. emit getCachedInfo( criteria, 2419200000, requestData );
  63. break;
  64. }
  65. default:
  66. {
  67. Q_ASSERT( false );
  68. break;
  69. }
  70. }
  71. }
  72. void
  73. MusicBrainzPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData )
  74. {
  75. switch ( requestData.type )
  76. {
  77. case InfoArtistReleases:
  78. {
  79. QString requestString( "http://musicbrainz.org/ws/2/artist" );
  80. QUrl url( requestString );
  81. url.addQueryItem( "query", criteria["artist"] );
  82. QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
  83. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  84. connect( reply, SIGNAL( finished() ), SLOT( artistSearchSlot() ) );
  85. break;
  86. }
  87. case InfoAlbumSongs:
  88. {
  89. QString requestString( "http://musicbrainz.org/ws/2/artist" );
  90. QUrl url( requestString );
  91. url.addQueryItem( "query", criteria["artist"] );
  92. QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
  93. reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
  94. connect( reply, SIGNAL( finished() ), SLOT( albumSearchSlot() ) );
  95. break;
  96. }
  97. default:
  98. {
  99. Q_ASSERT( false );
  100. break;
  101. }
  102. }
  103. }
  104. bool
  105. MusicBrainzPlugin::isValidTrackData( Tomahawk::InfoSystem::InfoRequestData requestData )
  106. {
  107. if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QVariantMap >() )
  108. {
  109. emit info( requestData, QVariant() );
  110. qDebug() << Q_FUNC_INFO << "Data null, invalid, or can't convert";
  111. return false;
  112. }
  113. QVariantMap hash = requestData.input.value< QVariantMap >();
  114. if ( hash[ "trackName" ].toString().isEmpty() )
  115. {
  116. emit info( requestData, QVariant() );
  117. qDebug() << Q_FUNC_INFO << "Track name is empty";
  118. return false;
  119. }
  120. if ( hash[ "artistName" ].toString().isEmpty() )
  121. {
  122. emit info( requestData, QVariant() );
  123. qDebug() << Q_FUNC_INFO << "No artist name found";
  124. return false;
  125. }
  126. return true;
  127. }
  128. void
  129. MusicBrainzPlugin::artistSearchSlot()
  130. {
  131. QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
  132. if ( !oldReply )
  133. return; //timeout will handle it
  134. QDomDocument doc;
  135. doc.setContent( oldReply->readAll() );
  136. QDomNodeList domNodeList = doc.elementsByTagName( "artist" );
  137. if ( domNodeList.isEmpty() )
  138. {
  139. emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
  140. tDebug() << Q_FUNC_INFO << doc.toString();
  141. return;
  142. }
  143. QString artist_id = domNodeList.at( 0 ).toElement().attribute( "id" );
  144. QString requestString( "http://musicbrainz.org/ws/2/release?status=official&type=album|ep" );
  145. QUrl url( requestString );
  146. url.addQueryItem( "artist", artist_id );
  147. QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
  148. newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
  149. connect( newReply, SIGNAL( finished() ), SLOT( albumFoundSlot() ) );
  150. }
  151. void
  152. MusicBrainzPlugin::albumSearchSlot()
  153. {
  154. QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
  155. if ( !oldReply )
  156. return; //timeout will handle it
  157. QDomDocument doc;
  158. doc.setContent( oldReply->readAll() );
  159. QDomNodeList domNodeList = doc.elementsByTagName( "artist" );
  160. if ( domNodeList.isEmpty() )
  161. {
  162. emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
  163. return;
  164. }
  165. QString artist_id = domNodeList.at( 0 ).toElement().attribute( "id" );
  166. QString requestString( "http://musicbrainz.org/ws/2/release?status=official&type=album|ep" );
  167. QUrl url( requestString );
  168. url.addQueryItem( "artist", artist_id );
  169. QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
  170. newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
  171. connect( newReply, SIGNAL( finished() ), SLOT( tracksSearchSlot() ) );
  172. }
  173. void
  174. MusicBrainzPlugin::tracksSearchSlot()
  175. {
  176. QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
  177. if ( !oldReply )
  178. return; //timeout will handle it
  179. QDomDocument doc;
  180. doc.setContent( oldReply->readAll() );
  181. QDomNodeList domNodeList = doc.elementsByTagName( "release" );
  182. if ( domNodeList.isEmpty() )
  183. {
  184. emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
  185. return;
  186. }
  187. Tomahawk::InfoSystem::InfoRequestData requestData = oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  188. InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
  189. QDomElement element;
  190. for ( int i = 0; i < domNodeList.count(); i++ )
  191. {
  192. QDomNodeList albumNodeList = domNodeList.at( i ).toElement().elementsByTagName( "title" );
  193. if ( albumNodeList.at( 0 ).toElement().text() == hash["album"] )
  194. element = domNodeList.at( i ).toElement();
  195. }
  196. if ( element.isNull() )
  197. {
  198. emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
  199. return;
  200. }
  201. QString release_id = element.attribute( "id" );
  202. QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1?inc=recordings" ).arg( release_id );
  203. QUrl url( requestString );
  204. QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
  205. newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
  206. connect( newReply, SIGNAL( finished() ), SLOT( tracksFoundSlot() ) );
  207. }
  208. void
  209. MusicBrainzPlugin::albumFoundSlot()
  210. {
  211. QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
  212. if ( !reply )
  213. return; //timeout will handle it
  214. QDomDocument doc;
  215. doc.setContent( reply->readAll() );
  216. QDomNodeList domNodeList = doc.elementsByTagName( "title" );
  217. if ( domNodeList.isEmpty() )
  218. {
  219. emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
  220. return;
  221. }
  222. QStringList albums;
  223. for ( int i = 0; i < domNodeList.count(); i++ )
  224. {
  225. QString album = domNodeList.at( i ).toElement().text();
  226. if ( !albums.contains( album ) )
  227. albums << album;
  228. }
  229. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  230. QVariantMap returnedData;
  231. returnedData["albums"] = albums;
  232. emit info( requestData, returnedData );
  233. Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
  234. Tomahawk::InfoSystem::InfoStringHash criteria;
  235. criteria["artist"] = origData["artist"];
  236. emit updateCache( criteria, 0, requestData.type, returnedData );
  237. }
  238. void
  239. MusicBrainzPlugin::tracksFoundSlot()
  240. {
  241. QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
  242. if ( !reply )
  243. return; //timeout will handle it
  244. QDomDocument doc;
  245. doc.setContent( reply->readAll() );
  246. QDomNodeList domNodeList = doc.elementsByTagName( "recording" );
  247. if ( domNodeList.isEmpty() )
  248. {
  249. emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
  250. return;
  251. }
  252. QStringList tracks;
  253. for ( int i = 0; i < domNodeList.count(); i++ )
  254. {
  255. QDomNodeList trackNodeList = domNodeList.at( i ).toElement().elementsByTagName( "title" );
  256. for ( int j = 0; j < trackNodeList.count(); j++ )
  257. {
  258. QString track = trackNodeList.at( j ).toElement().text();
  259. if ( !tracks.contains( track ) )
  260. tracks << track;
  261. }
  262. }
  263. Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
  264. QVariantMap returnedData;
  265. returnedData["tracks"] = tracks;
  266. emit info( requestData, returnedData );
  267. Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
  268. Tomahawk::InfoSystem::InfoStringHash criteria;
  269. criteria["artist"] = origData["artist"];
  270. criteria["album"] = origData["album"];
  271. emit updateCache( criteria, 0, requestData.type, returnedData );
  272. }