File indexing completed on 2025-01-19 04:24:32
0001 /**************************************************************************************** 0002 * Copyright (c) 2010 Andrew Coder <andrew.coder@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #define DEBUG_PREFIX "Playdar::Controller" 0018 0019 #include "Controller.h" 0020 0021 #include "Query.h" 0022 #include "core/support/Debug.h" 0023 0024 #include <QJsonDocument> 0025 #include <QJsonObject> 0026 #include <QJsonParseError> 0027 #include <QMap> 0028 #include <QString> 0029 #include <QUrl> 0030 #include <QUrlQuery> 0031 #include <QVariant> 0032 #include <QVariantMap> 0033 0034 #include <KIO/Job> 0035 0036 0037 namespace Playdar { 0038 0039 Controller::Controller( bool queriesShouldWaitForSolutions ) 0040 : m_errorState( ErrorState( NoError ) ) 0041 , m_queriesShouldWaitForSolutions( queriesShouldWaitForSolutions ) 0042 0043 { 0044 DEBUG_BLOCK 0045 } 0046 0047 Controller::~Controller() 0048 { 0049 DEBUG_BLOCK 0050 } 0051 0052 void 0053 Controller::resolve( const QString &artist, const QString &album, const QString &title ) 0054 { 0055 DEBUG_BLOCK 0056 0057 debug() << "Querying playdar for artist name = " << artist 0058 << ", album name = " << album << ", and track title = " << title; 0059 0060 const QString baseUrl( "http://localhost:60210/api/?method=resolve" ); 0061 QUrl resolveUrl( baseUrl ); 0062 QUrlQuery query( resolveUrl ); 0063 query.addQueryItem( QString( "artist" ), artist ); 0064 query.addQueryItem( QString( "album" ), album ); 0065 query.addQueryItem( QString( "track" ), title ); 0066 resolveUrl.setQuery( query ); 0067 0068 debug() << "Starting storedGetJob for " << resolveUrl.url(); 0069 0070 KJob* resolveJob = KIO::storedGet( resolveUrl, KIO::Reload, KIO::HideProgressInfo ); 0071 connect( resolveJob, &KJob::result, this, &Controller::processQuery ); 0072 } 0073 0074 void 0075 Controller::getResults( Query* query ) 0076 { 0077 DEBUG_BLOCK 0078 0079 const QString baseUrl( "http://localhost:60210/api/?method=get_results" ); 0080 QUrl getResultsUrl( baseUrl ); 0081 QUrlQuery q( getResultsUrl ); 0082 0083 q.addQueryItem( QString( "qid" ), query->qid() ); 0084 getResultsUrl.setQuery( q ); 0085 0086 KJob* getResultsJob = KIO::storedGet( getResultsUrl, KIO::Reload, KIO::HideProgressInfo ); 0087 connect( getResultsJob, &KJob::result, query, &Query::receiveResults ); 0088 } 0089 0090 void 0091 Controller::getResultsLongPoll( Query* query ) 0092 { 0093 DEBUG_BLOCK 0094 0095 const QString baseUrl( "http://localhost:60210/api/?method=get_results_long" ); 0096 QUrl getResultsUrl( baseUrl ); 0097 QUrlQuery q( getResultsUrl ); 0098 0099 q.addQueryItem( QString( "qid" ), query->qid() ); 0100 getResultsUrl.setQuery( q ); 0101 0102 KJob* getResultsJob = KIO::storedGet( getResultsUrl, KIO::Reload, KIO::HideProgressInfo ); 0103 connect( getResultsJob, &KJob::result, query, &Query::receiveResults ); 0104 } 0105 0106 QUrl 0107 Controller::urlForSid( const QString &sid ) const 0108 { 0109 DEBUG_BLOCK 0110 0111 const QString baseUrl( "http://localhost:60210/sid/" ); 0112 QUrl playableUrl( baseUrl ); 0113 0114 playableUrl = playableUrl.adjusted(QUrl::StripTrailingSlash); 0115 playableUrl.setPath(playableUrl.path() + QLatin1Char('/') + ( sid )); 0116 0117 return playableUrl; 0118 } 0119 0120 void 0121 Controller::status() 0122 { 0123 // DEBUG_BLOCK 0124 0125 const QString baseUrl( "http://localhost:60210/api/?method=stat" ); 0126 QUrl statusUrl( baseUrl ); 0127 0128 KJob* statusJob = KIO::storedGet( statusUrl, KIO::Reload, KIO::HideProgressInfo ); 0129 connect( statusJob, &KJob::result, this, &Controller::processStatus ); 0130 } 0131 0132 void 0133 Controller::processStatus( KJob *statusJob ) 0134 { 0135 if( statusJob->error() != 0 ) { 0136 // debug() << "Error getting status from Playdar"; 0137 Q_EMIT playdarError( Playdar::Controller::ErrorState( ExternalError ) ); 0138 return; 0139 } 0140 0141 debug() << "Processing received JSON data..."; 0142 KIO::StoredTransferJob* storedStatusJob = static_cast<KIO::StoredTransferJob*>( statusJob ); 0143 0144 QJsonParseError err; 0145 auto doc = QJsonDocument::fromJson( storedStatusJob->data(), &err ); 0146 0147 if ( err.error != QJsonParseError::NoError ) 0148 debug() << "Error parsing JSON Data:" << err.errorString(); 0149 0150 if( !doc.isObject() ) 0151 { 0152 debug() << "Parsed Json data is not an object"; 0153 return; 0154 } 0155 0156 auto object = doc.object(); 0157 0158 if( !object.contains("name") ) 0159 { 0160 debug() << "Expected a service name from Playdar, received none"; 0161 Q_EMIT playdarError( Playdar::Controller::ErrorState( MissingServiceName ) ); 0162 return; 0163 } 0164 if( object.value("name").toString() != QStringLiteral( "playdar" ) ) 0165 { 0166 debug() << "Expected Playdar, got response from some other service"; 0167 Q_EMIT playdarError( Playdar::Controller::ErrorState( WrongServiceName ) ); 0168 return; 0169 } 0170 0171 debug() << "All good! Emitting playdarReady()"; 0172 Q_EMIT playdarReady(); 0173 } 0174 0175 void 0176 Controller::processQuery( KJob *queryJob ) 0177 { 0178 DEBUG_BLOCK 0179 0180 if( queryJob->error() != 0 ) 0181 { 0182 debug() << "Error getting qid from Playdar"; 0183 Q_EMIT playdarError( Playdar::Controller::ErrorState( ExternalError ) ); 0184 return; 0185 } 0186 0187 debug() << "Processing received JSON data..."; 0188 KIO::StoredTransferJob* storedQueryJob = 0189 static_cast<KIO::StoredTransferJob*>( queryJob ); 0190 0191 QJsonParseError err; 0192 auto doc = QJsonDocument::fromJson( storedQueryJob->data(), &err ); 0193 0194 if ( err.error != QJsonParseError::NoError ) 0195 debug() << "Error parsing JSON Data:" << err.errorString(); 0196 0197 if( !doc.isObject() ) 0198 { 0199 debug() << "Parsed Json data is not an object"; 0200 return; 0201 } 0202 0203 auto object = doc.object(); 0204 0205 if( !object.contains( "qid" ) ) 0206 { 0207 debug() << "Expected qid in Playdar's response, but didn't get it"; 0208 Q_EMIT playdarError( Playdar::Controller::ErrorState( MissingQid ) ); 0209 return; 0210 } 0211 0212 Query* query = new Query( object.value( "qid" ).toString(), this, m_queriesShouldWaitForSolutions ); 0213 0214 debug() << "All good! Emitting queryReady( Playdar::Query* )..."; 0215 Q_EMIT queryReady( query ); 0216 0217 connect( query, &Query::playdarError, this, &Controller::playdarError ); 0218 } 0219 }