File indexing completed on 2025-01-05 04:26:04

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 #ifndef PLAYDAR_CONTROLLER_H
0018 #define PLAYDAR_CONTROLLER_H
0019 
0020 #include <QObject>
0021 #include <QPointer>
0022 
0023 class QUrl;
0024 class KJob;
0025 
0026 class QString;
0027 
0028 /**
0029  * @namespace Playdar contains the implementation of the Playdar API
0030  * in Amarok, so far as it is not specific to collection or context use.
0031  */
0032 namespace Playdar
0033 {
0034     class Query;
0035     
0036     /**
0037      * This class provides a basic interface to Playdar's resolution
0038      * functionality. A user should initialize a Controller, wait for
0039      * playdarReady(), and proceed to use resolve( artist, album, title )
0040      * as much as they'd like. Unless some error occurs, queryReady( QueryPtr )
0041      * will provide a QueryPtr for each call to resolve(). Results will
0042      * be provided by the appropriate Query as they become available, and
0043      * the friendly relationship between Controller and Query ensures that
0044      * results are properly matched with Queries.
0045      */
0046     class Controller : public QObject
0047     {
0048         Q_OBJECT
0049         public:
0050             /**
0051              * We invoke the private function status() here, return immediately,
0052              * and will Q_EMIT playdarReady() once things are actually set up.
0053              * @param queriesShouldWaitForSolutions
0054              *        If true, Playdar::Queries created by this controller will
0055              *        only use getResultsLongPoll instead of first using getResults.
0056              */
0057             explicit Controller( bool queriesShouldWaitForSolutions = false );
0058             /**
0059              * Controllers don't hold on to anything, so the deconstructor does nothing.
0060              */
0061             ~Controller() override;
0062             
0063             /** 
0064             * Asks Playdar for status information, which eventually results in
0065             * the emission of playdarReady() if it does or error() otherwise.
0066             */
0067             void status();
0068             
0069             /**
0070              * Asks Playdar to resolve a query, which eventually results in the
0071              * emission of queryReady() if okay, or error() if something goes wrong.
0072              * @param artist Name of artist to search for.
0073              * @param album Name of album (by artist) to search for.
0074              * @param title Name of track on album to search for.
0075              * NOTE: Currently, for a query to have any chance of being solved,
0076              *       both artist and title must be non-empty!
0077              */
0078             void resolve( const QString &artist,
0079                           const QString &album,
0080                           const QString &title );
0081             
0082             /** These errors are used when Playdar::Controller emits error(). */
0083             enum ErrorState
0084             {
0085                 /** Nothing bad happened yet! */
0086                 NoError,
0087                 /** Indicates an error from KIO or the Playdar service itself. */
0088                 ExternalError,
0089                 /** A request for status revealed a service claiming to not be Playdar. */
0090                 WrongServiceName,
0091                 /** A service asked for status didn't identify itself. */
0092                 MissingServiceName,
0093                 /** No "qid" field was found in a response to resolve() or getResults(). */
0094                 MissingQid,
0095                 /** Results were delivered to the wrong query */
0096                 WrongQid,
0097                 /** A response to getResults() didn't include a "results" array. */
0098                 MissingResults
0099             };
0100 
0101         Q_SIGNALS:
0102             /**
0103             * Emitted once after construction, as long as some service responds
0104             * from where we think Playdar is, and identifies itself as "playdar".
0105             * Clients shouldn't try to resolve things until they get this signal.
0106             */
0107             void playdarReady();
0108             /**
0109             * Emitted after resolve() is invoked, as long as Playdar's response
0110             * includes a "qid" field. If the client object's looking for results,
0111             * the Query's where they'll be when Playdar's got back to us. The
0112             * controller doesn't keep any QueryPtrs around, so interested clients
0113             * should keep a QueryList for any QueryPtrs they'd like to have.
0114             */
0115             void queryReady( Playdar::Query* );
0116             /**
0117             * Emitted after something unfortunate happens,
0118             * along with the (hopefully) appropriate ErrorType
0119             */
0120             void playdarError( Playdar::Controller::ErrorState );
0121         
0122         public:
0123             /**
0124              * NOTE: Queries handle invoking these on their own.
0125              */
0126             /**
0127              * Asks Playdar for the state of the query with @p qid.
0128              * If all goes well, resultsReady() is emitted, error() if something goes wrong.
0129              * @param query The query to get results for
0130              */
0131             void getResults( Playdar::Query* query );
0132             /**
0133              * Like getResults(), but Playdar will wait to respond until the query
0134              * has either been solved or enough time passes, (usually about 4000ms),
0135              * that the query would have been solved it was possible.
0136              * @param query The query to get results for
0137              */
0138             void getResultsLongPoll( Playdar::Query* query );
0139 
0140             /**
0141              * Makes a naive attempt to produce a QUrl that points to
0142              * a playable location of a query result.
0143              * @param sid The sid of the result desired.
0144              */
0145             QUrl urlForSid( const QString &sid ) const;
0146             
0147         private Q_SLOTS:
0148             void processStatus( KJob* statusJob );
0149             void processQuery( KJob* queryJob );
0150             
0151         private:
0152             ErrorState m_errorState;
0153             bool m_queriesShouldWaitForSolutions;
0154     };
0155 }
0156 
0157 #endif