1 /**************************************************************************************** 2 * Copyright (c) 2010 Andrew Coder <andrew.coder@gmail.com> * * 3 * This program is free software; you can redistribute it and/or modify it under * 4 * the terms of the GNU General Public License as published by the Free Software * 5 * Foundation; either version 2 of the License, or (at your option) any later * 6 * version. * 7 * * 8 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 10 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 11 * * 12 * You should have received a copy of the GNU General Public License along with * 13 * this program. If not, see <http://www.gnu.org/licenses/>. * 14 ****************************************************************************************/ 15 16 #include "Query.h" 17 18 #include "Controller.h" 19 #include "core/meta/Meta.h" 20 #include "../PlaydarMeta.h" 21 #include "core/support/Debug.h" 22 23 #include <QJsonArray> 24 #include <QJsonDocument> 25 #include <QJsonObject> 26 #include <QJsonParseError> 27 #include <QMap> 28 #include <QString> 29 #include <QUrl> 30 #include <QVariant> 31 #include <QVariantMap> 32 33 #include <KIO/Job> 34 35 36 namespace Playdar 37 { Query(const QString & qid,Playdar::Controller * controller,bool waitForSolution)38 Query::Query( const QString &qid, 39 Playdar::Controller* controller, 40 bool waitForSolution ) 41 : m_controller( controller ) 42 , m_waitForSolution( waitForSolution ) 43 , m_qid( qid ) 44 , m_artist( QString( "" ) ) 45 , m_album( QString( "" ) ) 46 , m_title( QString( "" ) ) 47 , m_solved( false ) 48 , m_receivedFirstResults( false ) 49 , m_trackList( ) 50 { 51 DEBUG_BLOCK 52 53 if( m_waitForSolution ) 54 { 55 m_receivedFirstResults = true; 56 m_controller->getResultsLongPoll( this ); 57 } 58 else 59 m_controller->getResults( this ); 60 } 61 ~Query()62 Query::~Query() 63 { 64 DEBUG_BLOCK 65 66 } 67 68 QString qid() const69 Query::qid() const 70 { 71 DEBUG_BLOCK 72 73 return m_qid; 74 } 75 76 QString artist() const77 Query::artist() const 78 { 79 DEBUG_BLOCK 80 81 return m_artist; 82 } 83 84 QString album() const85 Query::album() const 86 { 87 DEBUG_BLOCK 88 89 return m_album; 90 } 91 92 QString title() const93 Query::title() const 94 { 95 DEBUG_BLOCK 96 97 return m_title; 98 } 99 100 bool isSolved() const101 Query::isSolved() const 102 { 103 DEBUG_BLOCK 104 105 return m_solved; 106 } 107 108 Meta::PlaydarTrackList getTrackList() const109 Query::getTrackList() const 110 { 111 DEBUG_BLOCK 112 113 return m_trackList; 114 } 115 116 void receiveResults(KJob * resultsJob)117 Query::receiveResults( KJob* resultsJob) 118 { 119 DEBUG_BLOCK 120 121 if( resultsJob->error() != 0 ) { 122 debug() << "Error getting results from Playdar"; 123 Q_EMIT playdarError( Playdar::Controller::ErrorState( 1 ) ); 124 return; 125 } 126 127 debug() << "Processing received JSON data..."; 128 KIO::StoredTransferJob* storedResultsJob = static_cast<KIO::StoredTransferJob*>( resultsJob ); 129 130 QJsonParseError err; 131 auto doc = QJsonDocument::fromJson( storedResultsJob->data(), &err ); 132 133 if ( err.error != QJsonParseError::NoError ) 134 debug() << "Error parsing JSON Data:" << err.errorString(); 135 136 if( !doc.isObject() ) 137 { 138 debug() << "Parsed Json data is not an object"; 139 return; 140 } 141 142 auto object = doc.object(); 143 144 if( !object.contains( "results" ) ) 145 { 146 debug() << "Expecting results in Playdar's response, received none"; 147 Q_EMIT playdarError( Playdar::Controller::ErrorState( 6 ) ); 148 return; 149 } 150 if( !object.contains( "qid" ) ) 151 { 152 debug() << "Expected qid in Playdar's response, received none"; 153 Q_EMIT playdarError( Playdar::Controller::ErrorState( 4 ) ); 154 return; 155 } 156 if( object.value( "qid" ) != m_qid ) 157 { 158 debug() << "A query received the wrong results from Playdar..."; 159 Q_EMIT playdarError( Playdar::Controller::ErrorState( 5 ) ); 160 return; 161 } 162 163 m_artist = object.value( "artist" ).toString(); 164 m_album = object.value( "album" ).toString(); 165 m_title = object.value( "track" ).toString(); 166 167 for( const auto &resultVariant : object.value( "results" ).toArray() ) 168 { 169 auto result = resultVariant.toObject(); 170 Meta::PlaydarTrackPtr aTrack; 171 QUrl resultUrl( m_controller->urlForSid( result.value( "sid" ).toString() ) ); 172 173 QString trackSid = result.value( "sid" ).toString(); 174 QString trackUrl = resultUrl.url(); 175 QString trackTitle = result.value( "track" ).toString(); 176 QString trackArtist = result.value( "artist" ).toString(); 177 QString trackAlbum = result.value( "album" ).toString(); 178 QString trackType = result.value( "mimetype" ).toString(); 179 QString trackSource = result.value( "source" ).toString(); 180 qint64 trackLengthInSeconds( result.value( "duration" ).toInt() ); 181 aTrack = new Meta::PlaydarTrack 182 ( 183 trackSid, 184 trackUrl, 185 trackTitle, 186 trackArtist, 187 trackAlbum, 188 trackType, 189 result.value( "score" ).toDouble() * 100, 190 ( trackLengthInSeconds * 1000 ), //convert s to ms 191 result.value( "bitrate" ).toInt(), 192 result.value( "size" ).toInt(), 193 trackSource 194 ); 195 196 if( !m_solved && aTrack->score() >= 1.00 ) 197 { 198 m_solved = true; 199 m_trackList.prepend( aTrack ); 200 Q_EMIT querySolved( aTrack ); 201 202 if( m_waitForSolution ) 203 { 204 Q_EMIT queryDone( this, m_trackList ); 205 return; 206 } 207 } 208 else 209 { 210 m_trackList.append( aTrack ); 211 } 212 Q_EMIT newTrackAdded( aTrack ); 213 } 214 215 if( m_receivedFirstResults || m_solved ) 216 { 217 m_receivedFirstResults = true; 218 Q_EMIT queryDone( this, m_trackList ); 219 } 220 else 221 { 222 m_receivedFirstResults = true; 223 m_controller->getResultsLongPoll( this ); 224 } 225 } 226 } 227