1 /* -------------------------------------------------------------------------- 2 3 libmusicbrainz5 - Client library to access MusicBrainz 4 5 Copyright (C) 2012 Andrew Hawkins 6 7 This file is part of libmusicbrainz5. 8 9 This library is free software; you can redistribute it and/or 10 modify it under the terms of the GNU Lesser General Public 11 License as published by the Free Software Foundation; either 12 version 2.1 of the License, or (at your option) any later version. 13 14 libmusicbrainz5 is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 Lesser General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this library. If not, see <http://www.gnu.org/licenses/>. 21 22 $Id$ 23 24 ----------------------------------------------------------------------------*/ 25 26 #ifndef _MUSICBRAINZ5_QUERY_H 27 #define _MUSICBRAINZ5_QUERY_H 28 29 #include "defines.h" 30 31 #include "Entity.h" 32 33 #include "musicbrainz5/ReleaseList.h" 34 #include "musicbrainz5/Metadata.h" 35 36 #include "musicbrainz5/xmlParser.h" 37 38 #include <string> 39 #include <map> 40 #include <vector> 41 42 /** 43 * @mainpage libmusicbrainz5 44 * 45 * This is the documentation for libmusicbrainz5, a library for retrieving data from 46 * the <a target="_blank" href="http://musicbrainz.org">MusicBrainz</a> service. 47 * 48 * The main entry point to the library is the MusicBrainz5::CQuery object. 49 * 50 * For details of the C interface, see the documentation for the file mb5_c.h. 51 * 52 * Please report any issues with this library at 53 * <a target="_blank" href="http://tickets.musicbrainz.org/">http://tickets.musicbrainz.org/</a>. 54 * 55 * @par Compiling and Linking 56 * 57 * This package provides a pkg-config script that returns the necessary compiler 58 * and linker flags, as well as the version number. To build a small sample 59 * program one would use: 60 * 61 * @par 62 * <tt>g++ -o test_app test_app.cpp `pkg-config libmusicbrainz5 --cflags --libs`</tt> 63 * 64 * If you don't want/can't use pkg-config and you are using the C API, make sure 65 * you link in the C++ standard library: 66 * 67 * @par 68 * <tt>gcc -o test_app test_app.c -lmusicbrainz5 -lm -lstdc++</tt> 69 * 70 * @par Example: 71 * 72 * A brief example showing how to lookup a list of releases matching a disc id 73 * 74 @code 75 MusicBrainz5::CQuery Query("cdlookupexample-1.0"); 76 77 try 78 { 79 MusicBrainz5::CMetadata Metadata=Query.Query("discid",DiscID); 80 if (Metadata.Disc() && Metadata.Disc()->ReleaseList()) 81 { 82 MusicBrainz5::CReleaseList *ReleaseList=Metadata.Disc()->ReleaseList(); 83 84 std::cout << "Found " << ReleaseList->NumItems() << " release(s)" << std::endl; 85 86 for (int count=0;count<ReleaseList->NumItems();count++) 87 { 88 MusicBrainz5::CRelease *Release=ReleaseList->Item(count); 89 90 std::cout << "Basic release: " << std::endl << *Release << std::endl; 91 92 //The releases returned from LookupDiscID don't contain full information 93 94 MusicBrainz5::CQuery::tParamMap Params; 95 Params["inc"]="artists labels recordings release-groups url-rels discids artist-credits"; 96 97 Metadata=Query.Query("release",Release.ID(),"",Params); 98 if (Metadata.Release()) 99 { 100 MusicBrainz5::CRelease *FullRelease=Metadata.Release(); 101 102 std::cout << *FullRelease << std::endl; 103 } 104 } 105 } 106 } 107 108 catch (MusicBrainz5::CConnectionError& Error) 109 { 110 std::cout << "Connection Exception: '" << Error.what() << "'" << std::endl; 111 std::cout << "LastResult: " << Query.LastResult() << std::endl; 112 std::cout << "LastHTTPCode: " << Query.LastHTTPCode() << std::endl; 113 std::cout << "LastErrorMessage: " << Query.LastErrorMessage() << std::endl; 114 } 115 116 catch (MusicBrainz5::CTimeoutError& Error) 117 { 118 std::cout << "Timeout Exception: '" << Error.what() << "'" << std::endl; 119 std::cout << "LastResult: " << Query.LastResult() << std::endl; 120 std::cout << "LastHTTPCode: " << Query.LastHTTPCode() << std::endl; 121 std::cout << "LastErrorMessage: " << Query.LastErrorMessage() << std::endl; 122 } 123 124 catch (MusicBrainz5::CAuthenticationError& Error) 125 { 126 std::cout << "Authentication Exception: '" << Error.what() << "'" << std::endl; 127 std::cout << "LastResult: " << Query.LastResult() << std::endl; 128 std::cout << "LastHTTPCode: " << Query.LastHTTPCode() << std::endl; 129 std::cout << "LastErrorMessage: " << Query.LastErrorMessage() << std::endl; 130 } 131 132 catch (MusicBrainz5::CFetchError& Error) 133 { 134 std::cout << "Fetch Exception: '" << Error.what() << "'" << std::endl; 135 std::cout << "LastResult: " << Query.LastResult() << std::endl; 136 std::cout << "LastHTTPCode: " << Query.LastHTTPCode() << std::endl; 137 std::cout << "LastErrorMessage: " << Query.LastErrorMessage() << std::endl; 138 } 139 140 catch (MusicBrainz5::CRequestError& Error) 141 { 142 std::cout << "Request Exception: '" << Error.what() << "'" << std::endl; 143 std::cout << "LastResult: " << Query.LastResult() << std::endl; 144 std::cout << "LastHTTPCode: " << Query.LastHTTPCode() << std::endl; 145 std::cout << "LastErrorMessage: " << Query.LastErrorMessage() << std::endl; 146 } 147 148 catch (MusicBrainz5::CResourceNotFoundError& Error) 149 { 150 std::cout << "ResourceNotFound Exception: '" << Error.what() << "'" << std::endl; 151 std::cout << "LastResult: " << Query.LastResult() << std::endl; 152 std::cout << "LastHTTPCode: " << Query.LastHTTPCode() << std::endl; 153 std::cout << "LastErrorMessage: " << Query.LastErrorMessage() << std::endl; 154 } 155 @endcode 156 */ 157 158 namespace MusicBrainz5 159 { 160 class CQueryPrivate; 161 162 /** 163 * @brief Main object for generating queries to MusicBrainz 164 * 165 * This object is the main entry point for the library, generating a query to the 166 * MusicBrainz service, and parsing the results. The resultant objects can be used 167 * to retrieve information appropriate to the query. 168 * 169 * For information on generating queries and the expected responses, see the 170 * documentation for the 171 * <a target="_blank" href="http://musicbrainz.org/doc/XML_Web_Service/Version_2">web service</a>. 172 * 173 * For information on search syntax, see the documentation for 174 * <a target="_blank" href="http://wiki.musicbrainz.org/Text_Search_Syntax">search syntax</a>. 175 * 176 * @b Note It is the responsibility of the caller to validate any pointers returned 177 * from the library. It is valid for a pointer to be NULL if the information was not 178 * present in the response from the MusicBrainz service. 179 * 180 * @b Note The ownership of any pointers returned from the C++ interfaces remains 181 * with the library. The caller should not delete any pointer returned from the 182 * library. Users of the C library should take note of the documentation for each 183 * individual function in mb5_c.h 184 */ 185 class CQuery 186 { 187 public: 188 typedef std::map<std::string,std::string> tParamMap; 189 190 /** 191 * @brief Enumerated type for query status 192 * 193 * Enumerated type for query status 194 */ 195 enum tQueryResult 196 { 197 eQuery_Success=0, 198 eQuery_ConnectionError, 199 eQuery_Timeout, 200 eQuery_AuthenticationError, 201 eQuery_FetchError, 202 eQuery_RequestError, 203 eQuery_ResourceNotFound 204 }; 205 206 /** 207 * @brief Constructor for MusicBrainz::CQuery object 208 * 209 * This is the constructor for the MusicBrainz::CQuery object. 210 * 211 * @param UserAgent User agent to use in any queries and submissions. The format 212 * is @c "application-version", where application is your application's name 213 * and version is a version number which may not contain a '-' character. 214 * @param Server Server to be used (defaults to musicbrainz.org if not specified) 215 * @param Port Port to use (defaults to 80 if not specified) 216 * 217 */ 218 219 CQuery(const std::string& UserAgent, const std::string& Server="musicbrainz.org", int Port=80); 220 221 ~CQuery(); 222 223 /** 224 * @brief Set the user name 225 * 226 * Set the user name to use when authenticating to the MusicBrainz service 227 * 228 * @param UserName Username to use 229 */ 230 231 void SetUserName(const std::string& UserName); 232 233 /** 234 * @brief Set the password 235 * 236 * Set the password to use when authenticating to the MusicBrainz service 237 * 238 * @param Password Password to use 239 */ 240 241 void SetPassword(const std::string& Password); 242 243 /** 244 * @brief Set proxy server 245 * 246 * Set the proxy server to use for queries. @b Note The http_proxy environment variable 247 * will be used to set a 'default' proxy server. Calls to this method will override any 248 * proxy settings set by the http_proxy environment variable. 249 * 250 * @param ProxyHost Proxy server to use 251 */ 252 253 void SetProxyHost(const std::string& ProxyHost); 254 255 /** 256 * @brief Set proxy server port 257 * 258 * Set the proxy server port to use for queries. @b Note The http_proxy environment variable 259 * will be used to set a 'default' proxy server. Calls to this method will override any 260 * proxy settings set by the http_proxy environment variable. 261 * 262 * @param ProxyPort Proxy port to use 263 */ 264 265 void SetProxyPort(int ProxyPort); 266 267 /** 268 * @brief Set proxy server user name 269 * 270 * Set the user name to use when authenticating to the proxy server. @b Note The http_proxy 271 * environment variable will be used to set a 'default' proxy server. Calls to this method 272 * will override any proxy settings set by the http_proxy environment variable. 273 * 274 * @param ProxyUserName Proxy user name to use 275 */ 276 277 void SetProxyUserName(const std::string& ProxyUserName); 278 279 /** 280 * @brief Set proxy server password 281 * 282 * Set the password to use when authenticating to the proxy server. @b Note The http_proxy 283 * environment variable will be used to set a 'default' proxy server. Calls to this method 284 * will override any proxy settings set by the http_proxy environment variable. 285 * 286 * @param ProxyPassword Proxy password to use 287 */ 288 289 void SetProxyPassword(const std::string& ProxyPassword); 290 291 /** 292 * @brief Return a list of releases that match a disc ID 293 * 294 * Request a list of releases matching the specified disc ID. 295 * 296 * @param DiscID Disc id to match 297 * 298 * @return MusicBrainz5::CReleaseList 299 */ 300 301 CReleaseList LookupDiscID(const std::string& DiscID); 302 303 /** 304 * @brief Return full information about a release 305 * 306 * Query for detailed information about a specific release 307 * 308 * @param ReleaseID MusicBrainz release ID to lookup 309 * 310 * @return MusicBrainz::CRelease object 311 * 312 * @throw CConnectionError An error occurred connecting to the web server 313 * @throw CTimeoutError A timeout occurred when connecting to the web server 314 * @throw CAuthenticationError An authentication error occurred 315 * @throw CFetchError An error occurred fetching data 316 * @throw CRequestError The request was invalid 317 * @throw CResourceNotFoundError The requested resource was not found 318 */ 319 320 CRelease LookupRelease(const std::string& ReleaseID); 321 322 /** 323 * @brief Perform a generic query 324 * 325 * Performs a generic query. 326 * 327 * Assuming the following parameters are set: 328 * 329 * "param1" = "p1v1 p1v2 p1v3"<br> 330 * "param2" = "p2v1"<br> 331 * "param3" = ""<br> 332 * 333 * The following query will be generated: 334 * 335 * /ws/2/Entity/ID/Resource?param1=p1v1+p1v2+p1v3¶m2=p2v1¶m3 336 * 337 * If any of ID or Resource are empty, those components will be omitted from the query. 338 * 339 * For full details about generating queries, see the 340 * <a target="_blank" href="http://musicbrainz.org/doc/XML_Web_Service/Version_2">web service</a> 341 * documentation. 342 * 343 * @param Entity Entity to lookup (e.g. artist, release, discid) 344 * @param ID The MusicBrainz ID of the entity 345 * @param Resource The resource (currently only used for collections) 346 * @param Params Map of parameters to add to the query (e.g. inc) 347 * 348 * @return MusicBrainz5::CMetadata object 349 * 350 * @throw CConnectionError An error occurred connecting to the web server 351 * @throw CTimeoutError A timeout occurred when connecting to the web server 352 * @throw CAuthenticationError An authentication error occurred 353 * @throw CFetchError An error occurred fetching data 354 * @throw CRequestError The request was invalid 355 * @throw CResourceNotFoundError The requested resource was not found 356 */ 357 358 CMetadata Query(const std::string& Entity,const std::string& ID="",const std::string& Resource="",const tParamMap& Params=tParamMap()); 359 360 /** 361 * @brief Add entries to the specified collection 362 * 363 * Add a list of releases to the specified collection. 364 * 365 * @param CollectionID The MusicBrainz ID of the collection to add entries to 366 * @param Entries List of MusicBrainz Release IDs to add to the collection 367 * 368 * @return true if successful, false otherwise 369 * 370 * @throw CConnectionError An error occurred connecting to the web server 371 * @throw CTimeoutError A timeout occurred when connecting to the web server 372 * @throw CAuthenticationError An authentication error occurred 373 * @throw CFetchError An error occurred fetching data 374 * @throw CRequestError The request was invalid 375 * @throw CResourceNotFoundError The requested resource was not found 376 */ 377 378 bool AddCollectionEntries(const std::string& CollectionID, const std::vector<std::string>& Entries); 379 380 /** 381 * @brief Delete entries from the specified collection 382 * 383 * Delete a list of releases from the specified collection. 384 * 385 * @param CollectionID The MusicBrainz ID of the collection to delete entries from 386 * @param Entries List of MusicBrainz Release IDs to delete from the collection 387 * 388 * @return true if successful, false otherwise 389 * 390 * @throw CConnectionError An error occurred connecting to the web server 391 * @throw CTimeoutError A timeout occurred when connecting to the web server 392 * @throw CAuthenticationError An authentication error occurred 393 * @throw CFetchError An error occurred fetching data 394 * @throw CRequestError The request was invalid 395 * @throw CResourceNotFoundError The requested resource was not found 396 */ 397 398 bool DeleteCollectionEntries(const std::string& CollectionID, const std::vector<std::string>& Entries); 399 400 /** 401 * @brief Return result of the last query 402 * 403 * Return the result of the last query 404 * 405 * @return Result of last query 406 */ 407 408 CQuery::tQueryResult LastResult() const; 409 410 /** 411 * @brief Return HTTP code of the last query 412 * 413 * Return the HTTP code of the last query 414 * 415 * @return HTTP code of last query 416 */ 417 int LastHTTPCode() const; 418 419 /** 420 * @brief Return error message from the last query 421 * 422 * Return the error message from the last query 423 * 424 * @return Error message from last query 425 */ 426 std::string LastErrorMessage() const; 427 428 /** 429 * @brief Return the library version 430 * 431 * Return the library version 432 * 433 * @return Library version 434 */ 435 std::string Version() const; 436 437 private: 438 CQueryPrivate * const m_d; 439 440 CMetadata PerformQuery(const std::string& Query); 441 void WaitRequest() const; 442 std::string UserAgent() const; 443 bool EditCollection(const std::string& CollectionID, const std::vector<std::string>& Entries, const std::string& Action); 444 std::string URIEscape(const std::string& URI); 445 std::string URLEncode(const std::map<std::string,std::string>& Params); 446 }; 447 } 448 449 #endif 450