PageRenderTime 196ms CodeModel.GetById 70ms app.highlight 89ms RepoModel.GetById 32ms app.codeStats 0ms

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