rbrainz 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +13 -1
- data/LICENSE +1 -1
- data/README +2 -2
- data/Rakefile +2 -2
- data/TODO +9 -2
- data/doc/README.rdoc +5 -5
- data/examples/getartist.rb +3 -2
- data/examples/getlabel.rb +3 -2
- data/examples/getrelease.rb +5 -2
- data/examples/getreleasegroup.rb +53 -0
- data/examples/gettrack.rb +3 -2
- data/examples/getuser.rb +2 -1
- data/examples/rate.rb +44 -0
- data/examples/searchartists.rb +3 -2
- data/examples/searchcdstubs.rb +41 -0
- data/examples/searchlabels.rb +3 -2
- data/examples/searchreleasegroups.rb +36 -0
- data/examples/searchreleases.rb +6 -4
- data/examples/searchtracks.rb +3 -2
- data/examples/submit_isrcs.rb +52 -0
- data/examples/tag.rb +3 -2
- data/lib/rbrainz.rb +2 -1
- data/lib/rbrainz/core_ext.rb +2 -1
- data/lib/rbrainz/core_ext/mbid.rb +2 -1
- data/lib/rbrainz/core_ext/net_http_digest.rb +3 -2
- data/lib/rbrainz/core_ext/range.rb +3 -2
- data/lib/rbrainz/core_ext/range/equality.rb +2 -1
- data/lib/rbrainz/data/countrynames.rb +6 -3
- data/lib/rbrainz/data/languagenames.rb +3 -2
- data/lib/rbrainz/data/releasetypenames.rb +3 -2
- data/lib/rbrainz/data/scriptnames.rb +3 -2
- data/lib/rbrainz/model.rb +3 -2
- data/lib/rbrainz/model/alias.rb +3 -2
- data/lib/rbrainz/model/artist.rb +11 -3
- data/lib/rbrainz/model/collection.rb +3 -2
- data/lib/rbrainz/model/default_factory.rb +18 -6
- data/lib/rbrainz/model/disc.rb +3 -2
- data/lib/rbrainz/model/entity.rb +2 -102
- data/lib/rbrainz/model/incomplete_date.rb +3 -2
- data/lib/rbrainz/model/individual.rb +11 -2
- data/lib/rbrainz/model/isrc.rb +100 -0
- data/lib/rbrainz/model/label.rb +5 -2
- data/lib/rbrainz/model/mbid.rb +28 -9
- data/lib/rbrainz/model/rateable.rb +34 -0
- data/lib/rbrainz/model/rating.rb +56 -0
- data/lib/rbrainz/model/relateable.rb +118 -0
- data/lib/rbrainz/model/relation.rb +2 -1
- data/lib/rbrainz/model/release.rb +17 -3
- data/lib/rbrainz/model/release_event.rb +3 -2
- data/lib/rbrainz/model/release_group.rb +97 -0
- data/lib/rbrainz/model/scored_collection.rb +3 -2
- data/lib/rbrainz/model/tag.rb +5 -4
- data/lib/rbrainz/model/taggable.rb +27 -0
- data/lib/rbrainz/model/track.rb +15 -2
- data/lib/rbrainz/model/user.rb +3 -2
- data/lib/rbrainz/utils.rb +2 -1
- data/lib/rbrainz/utils/data.rb +3 -2
- data/lib/rbrainz/utils/helper.rb +8 -2
- data/lib/rbrainz/version.rb +3 -2
- data/lib/rbrainz/webservice.rb +12 -7
- data/lib/rbrainz/webservice/filter.rb +53 -4
- data/lib/rbrainz/webservice/includes.rb +72 -11
- data/lib/rbrainz/webservice/mbxml.rb +129 -67
- data/lib/rbrainz/webservice/query.rb +156 -16
- data/lib/rbrainz/webservice/webservice.rb +104 -116
- data/test/lib/mock_webservice.rb +9 -2
- data/test/lib/test_entity.rb +2 -97
- data/test/lib/test_factory.rb +9 -1
- data/test/lib/test_rateable.rb +31 -0
- data/test/lib/test_relateable.rb +103 -0
- data/test/lib/test_taggable.rb +36 -0
- data/test/lib/testing_helper.rb +17 -2
- data/test/test-data/invalid/artist/ratings_1.xml +6 -0
- data/test/test-data/invalid/artist/ratings_2.xml +6 -0
- data/test/test-data/valid/artist/Tchaikovsky-2.xml +6 -0
- data/test/test-data/valid/label/Atlantic_Records_3.xml +6 -0
- data/test/test-data/valid/release-group/The_Cure_1.xml +36 -0
- data/test/test-data/valid/release/Highway_61_Revisited_2.xml +6 -0
- data/test/test-data/valid/track/Silent_All_These_Years_4.xml +3 -0
- data/test/test-data/valid/track/Silent_All_These_Years_6.xml +8 -0
- data/test/test_alias.rb +2 -1
- data/test/test_artist.rb +24 -2
- data/test/test_artist_filter.rb +2 -1
- data/test/test_artist_includes.rb +13 -3
- data/test/test_collection.rb +3 -2
- data/test/test_default_factory.rb +8 -1
- data/test/test_disc.rb +2 -1
- data/test/test_incomplete_date.rb +2 -1
- data/test/test_isrc.rb +87 -0
- data/test/test_label.rb +8 -1
- data/test/test_label_filter.rb +2 -1
- data/test/test_label_includes.rb +10 -3
- data/test/test_mbid.rb +2 -1
- data/test/test_mbxml.rb +93 -2
- data/test/test_query.rb +68 -5
- data/test/test_range_equality.rb +2 -1
- data/test/test_rating.rb +46 -0
- data/test/test_relation.rb +2 -1
- data/test/test_release.rb +37 -2
- data/test/test_release_event.rb +2 -1
- data/test/test_release_filter.rb +15 -2
- data/test/test_release_group.rb +104 -0
- data/test/test_release_group_filter.rb +61 -0
- data/test/test_release_group_includes.rb +46 -0
- data/test/test_release_includes.rb +16 -3
- data/test/test_scored_collection.rb +3 -2
- data/test/test_tag.rb +2 -1
- data/test/test_track.rb +28 -1
- data/test/test_track_filter.rb +2 -1
- data/test/test_track_includes.rb +13 -3
- data/test/test_utils.rb +2 -1
- data/test/test_webservice.rb +11 -1
- metadata +38 -20
- data/debian/changelog +0 -11
- data/debian/compat +0 -1
- data/debian/control +0 -13
- data/debian/copyright +0 -25
- data/debian/rules +0 -48
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# $Id: query.rb 270 2009-05-24 22:15:29Z phw $
|
|
2
3
|
#
|
|
3
4
|
# Author:: Philipp Wolfer (mailto:phw@rubyforge.org)
|
|
4
5
|
# Copyright:: Copyright (c) 2007, Nigel Graham, Philipp Wolfer
|
|
@@ -179,7 +180,7 @@ module MusicBrainz
|
|
|
179
180
|
# or a options hash as expected by ArtistIncludes.
|
|
180
181
|
#
|
|
181
182
|
# If no artist with that ID can be found, include contains invalid tags
|
|
182
|
-
# or there's a server problem,
|
|
183
|
+
# or there's a server problem, an exception is raised.
|
|
183
184
|
#
|
|
184
185
|
# Raises:: ConnectionError, RequestError, ResourceNotFoundError, ResponseError
|
|
185
186
|
def get_artist_by_id(id, includes = nil)
|
|
@@ -187,10 +188,10 @@ module MusicBrainz
|
|
|
187
188
|
return get_entity_by_id(Model::Artist.entity_type, id, includes)
|
|
188
189
|
end
|
|
189
190
|
|
|
190
|
-
# Returns artists matching given criteria.
|
|
191
|
+
# Returns artists matching the given criteria.
|
|
191
192
|
#
|
|
192
193
|
# The parameter _filter_ must be an instance of ArtistFilter
|
|
193
|
-
# or
|
|
194
|
+
# or an option hash as expected by ArtistFilter.
|
|
194
195
|
#
|
|
195
196
|
# Raises:: ConnectionError, RequestError, ResponseError
|
|
196
197
|
def get_artists(filter)
|
|
@@ -198,13 +199,38 @@ module MusicBrainz
|
|
|
198
199
|
return get_entities(Model::Artist.entity_type, filter)
|
|
199
200
|
end
|
|
200
201
|
|
|
201
|
-
# Returns
|
|
202
|
+
# Returns a release group.
|
|
203
|
+
#
|
|
204
|
+
# The parameter _includes_ must be an instance of ReleaseGroupIncludes
|
|
205
|
+
# or a options hash as expected by ReleaseGroupIncludes.
|
|
206
|
+
#
|
|
207
|
+
# If no release group with that ID can be found, include contains invalid
|
|
208
|
+
# tags or there's a server problem, an exception is raised.
|
|
209
|
+
#
|
|
210
|
+
# Raises:: ConnectionError, RequestError, ResourceNotFoundError, ResponseError
|
|
211
|
+
def get_release_group_by_id(id, includes = nil)
|
|
212
|
+
includes = ReleaseGroupIncludes.new(includes) unless includes.nil? || includes.is_a?(ReleaseGroupIncludes)
|
|
213
|
+
return get_entity_by_id(Model::ReleaseGroup.entity_type, id, includes)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Returns release groups matching the given criteria.
|
|
217
|
+
#
|
|
218
|
+
# The parameter _filter_ must be an instance of ReleaseGroupFilter
|
|
219
|
+
# or an option hash as expected by ReleaseGroupFilter.
|
|
220
|
+
#
|
|
221
|
+
# Raises:: ConnectionError, RequestError, ResponseError
|
|
222
|
+
def get_release_groups(filter)
|
|
223
|
+
filter = ReleaseGroupFilter.new(filter) unless filter.nil? || filter.is_a?(ReleaseGroupFilter)
|
|
224
|
+
return get_entities(Model::ReleaseGroup.entity_type, filter)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Returns a release.
|
|
202
228
|
#
|
|
203
229
|
# The parameter _includes_ must be an instance of ReleaseIncludes
|
|
204
230
|
# or a options hash as expected by ReleaseIncludes.
|
|
205
231
|
#
|
|
206
232
|
# If no release with that ID can be found, include contains invalid tags
|
|
207
|
-
# or there's a server problem,
|
|
233
|
+
# or there's a server problem, an exception is raised.
|
|
208
234
|
#
|
|
209
235
|
# Raises:: ConnectionError, RequestError, ResourceNotFoundError, ResponseError
|
|
210
236
|
def get_release_by_id(id, includes = nil)
|
|
@@ -212,10 +238,10 @@ module MusicBrainz
|
|
|
212
238
|
return get_entity_by_id(Model::Release.entity_type, id, includes)
|
|
213
239
|
end
|
|
214
240
|
|
|
215
|
-
# Returns releases matching given criteria.
|
|
241
|
+
# Returns releases matching the given criteria.
|
|
216
242
|
#
|
|
217
243
|
# The parameter _filter_ must be an instance of ReleaseFilter
|
|
218
|
-
# or
|
|
244
|
+
# or an option hash as expected by ReleaseFilter.
|
|
219
245
|
#
|
|
220
246
|
# Raises:: ConnectionError, RequestError, ResponseError
|
|
221
247
|
def get_releases(filter)
|
|
@@ -223,13 +249,13 @@ module MusicBrainz
|
|
|
223
249
|
return get_entities(Model::Release.entity_type, filter)
|
|
224
250
|
end
|
|
225
251
|
|
|
226
|
-
# Returns
|
|
252
|
+
# Returns a track.
|
|
227
253
|
#
|
|
228
254
|
# The parameter _includes_ must be an instance of TrackIncludes
|
|
229
255
|
# or a options hash as expected by TrackIncludes.
|
|
230
256
|
#
|
|
231
257
|
# If no track with that ID can be found, include contains invalid tags
|
|
232
|
-
# or there's a server problem,
|
|
258
|
+
# or there's a server problem, an exception is raised.
|
|
233
259
|
#
|
|
234
260
|
# Raises:: ConnectionError, RequestError, ResourceNotFoundError, ResponseError
|
|
235
261
|
def get_track_by_id(id, includes = nil)
|
|
@@ -237,10 +263,10 @@ module MusicBrainz
|
|
|
237
263
|
return get_entity_by_id(Model::Track.entity_type, id, includes)
|
|
238
264
|
end
|
|
239
265
|
|
|
240
|
-
# Returns tracks matching given criteria.
|
|
266
|
+
# Returns tracks matching the given criteria.
|
|
241
267
|
#
|
|
242
268
|
# The parameter _filter_ must be an instance of TrackFilter
|
|
243
|
-
# or
|
|
269
|
+
# or an option hash as expected by TrackFilter.
|
|
244
270
|
#
|
|
245
271
|
# Raises:: ConnectionError, RequestError, ResponseError
|
|
246
272
|
def get_tracks(filter)
|
|
@@ -295,7 +321,7 @@ module MusicBrainz
|
|
|
295
321
|
# Submit track to PUID mappings.
|
|
296
322
|
#
|
|
297
323
|
# The <em>tracks2puids</em> parameter has to be a Hash or Array
|
|
298
|
-
# with track ID/PUID pairs. The track IDs are either instances of MBID,
|
|
324
|
+
# with track ID/PUID pairs. The track IDs are either instances of Model::MBID,
|
|
299
325
|
# absolute URIs or the 36 character ASCII representation. PUIDs are
|
|
300
326
|
# 36 characters ASCII strings.
|
|
301
327
|
#
|
|
@@ -333,9 +359,59 @@ module MusicBrainz
|
|
|
333
359
|
@webservice.post(:track, :params=>params)
|
|
334
360
|
end
|
|
335
361
|
|
|
336
|
-
# Submit
|
|
362
|
+
# Submit track to ISRC mappings.
|
|
363
|
+
#
|
|
364
|
+
# The <em>tracks2isrcs</em> parameter has to be a Hash or Array
|
|
365
|
+
# with track ID/ISRC pairs. The track IDs are either instances of Model::MBID,
|
|
366
|
+
# absolute URIs or the 36 character ASCII representation. ISRCs are either
|
|
367
|
+
# instances of Model::ISRC or 12 character ASCII strings.
|
|
368
|
+
#
|
|
369
|
+
# Example:
|
|
370
|
+
# ws = Webservice::Webservice.new(
|
|
371
|
+
# :host => 'test.musicbrainz.org',
|
|
372
|
+
# :username => 'outsidecontext',
|
|
373
|
+
# :password => 'secret'
|
|
374
|
+
# )
|
|
375
|
+
#
|
|
376
|
+
# query = Webservice::Query.new(ws, :client_id=>'My Tagging App 1.0')
|
|
377
|
+
#
|
|
378
|
+
# query.submit_isrcs([
|
|
379
|
+
# ['7f574ec1-344c-4ae1-970d-3c757f9a717e', 'DED830049301'],
|
|
380
|
+
# ['1393122c-364c-4fb6-9a4b-17eddce90152', 'DED830049302'],
|
|
381
|
+
# ['2634965c-5299-4958-b0dc-47b166bb6898', 'DED830049303'],
|
|
382
|
+
# ['dad6b8a4-0412-4a80-9123-3e0ebddaf82d', 'DED830049304'],
|
|
383
|
+
# ['e1f7e805-33f3-4663-b294-3805b82405f9', 'DED830049305'],
|
|
384
|
+
# ['d9f932ad-de0d-44ca-bf35-ae8184f63909', 'DED830049306'],
|
|
385
|
+
# ['c983b62d-f528-433f-a402-a6317ce3d2d8', 'DED830049307'],
|
|
386
|
+
# ['9d50b06a-4136-427f-8d11-b2efb0141da6', 'DED830049308'],
|
|
387
|
+
# ['f2af3e3f-3f9f-4f8d-8b60-1d1b709aaf69', 'DED830049309'],
|
|
388
|
+
# ['059384bc-fb45-445e-ab77-950d6ccf587a', 'DED830049310'],
|
|
389
|
+
# ['2f4d7b47-a4ba-495a-b447-60b8287ed9c9', 'DED830049311'],
|
|
390
|
+
# ])
|
|
391
|
+
#
|
|
392
|
+
# Note that this method only works if a valid user name and
|
|
393
|
+
# password have been set. If username and/or password are incorrect,
|
|
394
|
+
# an AuthenticationError is raised. See the example in Query on
|
|
395
|
+
# how to supply authentication data.
|
|
396
|
+
#
|
|
397
|
+
# See:: http://musicbrainz.org/doc/ISRC
|
|
398
|
+
# Raises:: ConnectionError, RequestError, AuthenticationError, InvalidISRCError
|
|
399
|
+
def submit_isrcs(tracks2isrcs)
|
|
400
|
+
raise RequestError, 'Please supply a client ID' unless @client_id
|
|
401
|
+
params = [['client', @client_id.to_s]] # Encoded as utf-8
|
|
402
|
+
|
|
403
|
+
tracks2isrcs.each do |track_id, isrc|
|
|
404
|
+
track_id = Model::MBID.parse(track_id, :track).uuid
|
|
405
|
+
isrc = Model::ISRC.parse(isrc)
|
|
406
|
+
params << ['isrc', track_id + ' ' + isrc.to_str ]
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
@webservice.post(:track, :params=>params)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
# Submit tags for an entity. _mbid_ must be an instance of Model::MBID identifying
|
|
337
413
|
# the entity the tag should applied to and _tags_ is either and array or
|
|
338
|
-
# Collection of Tag objects or a string with comma separated tags.
|
|
414
|
+
# Collection of Model::Tag objects or a string with comma separated tags.
|
|
339
415
|
#
|
|
340
416
|
# Note that this method only works if a valid user name and password have
|
|
341
417
|
# been set. The tags will be applied for the authenticated user. If
|
|
@@ -395,6 +471,70 @@ module MusicBrainz
|
|
|
395
471
|
return get_entities(:tag, "entity=#{mbid.entity}&id=#{mbid.uuid}").to_collection
|
|
396
472
|
end
|
|
397
473
|
|
|
474
|
+
# Submit the user's rating for an entity. _mbid_ must be an instance of
|
|
475
|
+
# Model::MBID identifying the entity which should be rated and _rating_ is
|
|
476
|
+
# either a Model::Rating object or an integer value between 0 and 5.
|
|
477
|
+
#
|
|
478
|
+
# Note that this method only works if a valid user name and password have
|
|
479
|
+
# been set. The tags will be applied for the authenticated user. If
|
|
480
|
+
# username and/or password are incorrect, an AuthenticationError is raised.
|
|
481
|
+
# See the example in Query on how to supply authentication data.
|
|
482
|
+
#
|
|
483
|
+
# Example:
|
|
484
|
+
# ws = Webservice::Webservice.new(
|
|
485
|
+
# :host => 'test.musicbrainz.org',
|
|
486
|
+
# :username => 'outsidecontext',
|
|
487
|
+
# :password => 'secret'
|
|
488
|
+
# )
|
|
489
|
+
#
|
|
490
|
+
# query = Webservice::Query.new(ws)
|
|
491
|
+
#
|
|
492
|
+
# mbid = Model::MBID.new('http://musicbrainz.org/artist/10bf95b6-30e3-44f1-817f-45762cdc0de0')
|
|
493
|
+
# query.submit_user_rating(mbid, 5)
|
|
494
|
+
#
|
|
495
|
+
# See:: Model::Rating
|
|
496
|
+
# Raises:: ConnectionError, RequestError, AuthenticationError
|
|
497
|
+
def submit_user_rating(mbid, rating)
|
|
498
|
+
mbid = Model::MBID.parse(mbid)
|
|
499
|
+
params = {:entity=>mbid.entity, :id=>mbid.uuid, :rating=>rating.to_i}
|
|
500
|
+
@webservice.post(:rating, :params=>params)
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
# Returns the Model::Rating a user has applied to the entity
|
|
504
|
+
# identified by _mbid_.
|
|
505
|
+
#
|
|
506
|
+
# Note that this method only works if a valid user name and password have
|
|
507
|
+
# been set. Only the tags the authenticated user applied to the entity will
|
|
508
|
+
# be returned. If username and/or password are incorrect, an
|
|
509
|
+
# AuthenticationError is raised. See the example in Query on how to supply
|
|
510
|
+
# authentication data.
|
|
511
|
+
#
|
|
512
|
+
# Example:
|
|
513
|
+
# ws = Webservice::Webservice.new(
|
|
514
|
+
# :host => 'test.musicbrainz.org',
|
|
515
|
+
# :username => 'outsidecontext',
|
|
516
|
+
# :password => 'secret'
|
|
517
|
+
# )
|
|
518
|
+
#
|
|
519
|
+
# query = Webservice::Query.new(ws)
|
|
520
|
+
#
|
|
521
|
+
# mbid = Model::MBID.new('http://musicbrainz.org/artist/10bf95b6-30e3-44f1-817f-45762cdc0de0')
|
|
522
|
+
# rating = query.get_user_rating(mbid)
|
|
523
|
+
#
|
|
524
|
+
# See:: Model::Rating
|
|
525
|
+
# Raises:: ConnectionError, RequestError, ResponseError, AuthenticationError
|
|
526
|
+
def get_user_rating(mbid)
|
|
527
|
+
mbid = Model::MBID.parse(mbid)
|
|
528
|
+
stream = @webservice.get(:rating, :filter => "entity=#{mbid.entity}&id=#{mbid.uuid}")
|
|
529
|
+
begin
|
|
530
|
+
rating = MBXML.new(stream, @factory).get_entity(:user_rating)
|
|
531
|
+
rescue MBXML::ParseError => e
|
|
532
|
+
raise ResponseError, e.to_s
|
|
533
|
+
end
|
|
534
|
+
rating = Model::Rating.new unless rating
|
|
535
|
+
return rating
|
|
536
|
+
end
|
|
537
|
+
|
|
398
538
|
private # ----------------------------------------------------------------
|
|
399
539
|
|
|
400
540
|
# Helper method which will return any entity by ID.
|
|
@@ -430,4 +570,4 @@ module MusicBrainz
|
|
|
430
570
|
end
|
|
431
571
|
|
|
432
572
|
end
|
|
433
|
-
end
|
|
573
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# $Id: webservice.rb
|
|
1
|
+
# $Id: webservice.rb 277 2009-05-25 19:33:26Z phw $
|
|
2
2
|
#
|
|
3
3
|
# Author:: Philipp Wolfer (mailto:phw@rubyforge.org)
|
|
4
4
|
# Copyright:: Copyright (c) 2007, Nigel Graham, Philipp Wolfer
|
|
@@ -72,7 +72,7 @@ module MusicBrainz
|
|
|
72
72
|
# [:username] The username to authenticate with.
|
|
73
73
|
# [:password] The password to authenticate with.
|
|
74
74
|
# [:user_agent] Value sent in the User-Agent HTTP header. Defaults to "rbrainz/#{RBRAINZ_VERSION}"
|
|
75
|
-
# [:proxy]
|
|
75
|
+
# [:proxy] URI for the proxy server to connect through
|
|
76
76
|
def initialize(options={ :host=>nil, :port=>nil, :path_prefix=>'/ws', :username=>nil, :password=>nil, :user_agent=>"rbrainz/#{RBRAINZ_VERSION}", :proxy=>nil })
|
|
77
77
|
Utils.check_options options, :host, :port, :path_prefix, :username, :password, :user_agent, :proxy
|
|
78
78
|
@host = options[:host] ? options[:host] : 'musicbrainz.org'
|
|
@@ -83,14 +83,7 @@ module MusicBrainz
|
|
|
83
83
|
@user_agent = options[:user_agent] ? options[:user_agent] : "rbrainz/#{RBRAINZ_VERSION}"
|
|
84
84
|
@open_timeout = nil
|
|
85
85
|
@read_timeout = nil
|
|
86
|
-
|
|
87
|
-
unless options[:proxy].nil?
|
|
88
|
-
uri = URI.parse( options[:proxy] )
|
|
89
|
-
@proxy[:host], @proxy[:port] = uri.host, uri.port
|
|
90
|
-
if uri.userinfo
|
|
91
|
-
@proxy[:username], @proxy[:password] = uri.userinfo.split(/:/)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
86
|
+
set_proxy_options(options)
|
|
94
87
|
end
|
|
95
88
|
|
|
96
89
|
# Query the Webservice with HTTP GET.
|
|
@@ -108,55 +101,9 @@ module MusicBrainz
|
|
|
108
101
|
# See:: IWebservice#get
|
|
109
102
|
def get(entity_type, options={ :id=>nil, :include=>nil, :filter=>nil, :version=>1 })
|
|
110
103
|
Utils.check_options options, :id, :include, :filter, :version
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
connection = Net::HTTP.new(url.host, url.port, @proxy[:host], @proxy[:port])
|
|
115
|
-
|
|
116
|
-
# Set timeouts
|
|
117
|
-
connection.open_timeout = @open_timeout if @open_timeout
|
|
118
|
-
connection.read_timeout = @read_timeout if @read_timeout
|
|
119
|
-
|
|
120
|
-
# Make the request
|
|
121
|
-
begin
|
|
122
|
-
response = connection.start do |http|
|
|
123
|
-
response = http.request(request)
|
|
124
|
-
if response.is_a?(Net::HTTPProxyAuthenticationRequired) && @proxy[:username] && @proxy[:password]
|
|
125
|
-
request = Net::HTTP::Post.new(url.request_uri)
|
|
126
|
-
request['User-Agent'] = @user_agent
|
|
127
|
-
request.proxy_select_auth(@proxy[:username], @proxy[:password], response)
|
|
128
|
-
request.set_form_data(options[:params])
|
|
129
|
-
response = http.request(request)
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
if response.is_a?(Net::HTTPUnauthorized) && @username && @password
|
|
133
|
-
request = Net::HTTP::Get.new(url.request_uri)
|
|
134
|
-
request['User-Agent'] = @user_agent
|
|
135
|
-
request.select_auth @username, @password, response
|
|
136
|
-
response = http.request(request)
|
|
137
|
-
end
|
|
138
|
-
response
|
|
139
|
-
end
|
|
140
|
-
rescue Timeout::Error, Errno::ETIMEDOUT
|
|
141
|
-
raise ConnectionError.new('%s timed out' % url.to_s)
|
|
142
|
-
rescue SocketError => e
|
|
143
|
-
raise ConnectionError.new('%s (%s)' % [url.to_s, e.to_s])
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# Handle response errors.
|
|
147
|
-
if response.is_a? Net::HTTPBadRequest # 400
|
|
148
|
-
raise RequestError.new(url.to_s)
|
|
149
|
-
elsif response.is_a? Net::HTTPUnauthorized # 401
|
|
150
|
-
raise AuthenticationError.new(url.to_s)
|
|
151
|
-
elsif response.is_a? Net::HTTPNotFound # 404
|
|
152
|
-
raise ResourceNotFoundError.new(url.to_s)
|
|
153
|
-
elsif response.is_a? Net::HTTPForbidden
|
|
154
|
-
raise AuthenticationError.new(url.to_s)
|
|
155
|
-
elsif not response.is_a? Net::HTTPSuccess
|
|
156
|
-
raise ConnectionError.new(response.class.name)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
return ::StringIO.new(response.body)
|
|
104
|
+
uri = create_uri(entity_type, options)
|
|
105
|
+
response = open_connection_and_make_request(uri, :get)
|
|
106
|
+
return response
|
|
160
107
|
end
|
|
161
108
|
|
|
162
109
|
# Send data to the web service via HTTP-POST.
|
|
@@ -177,68 +124,35 @@ module MusicBrainz
|
|
|
177
124
|
# See:: IWebservice#post
|
|
178
125
|
def post(entity_type, options={ :id=>nil, :params=>[], :version=>1 })
|
|
179
126
|
Utils.check_options options, :id, :params, :version
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
request.set_form_data(options[:params])
|
|
184
|
-
connection = Net::HTTP.new(url.host, url.port, @proxy[:host], @proxy[:port])
|
|
185
|
-
|
|
186
|
-
# Set timeouts
|
|
187
|
-
connection.open_timeout = @open_timeout if @open_timeout
|
|
188
|
-
connection.read_timeout = @read_timeout if @read_timeout
|
|
189
|
-
|
|
190
|
-
# Make the request
|
|
191
|
-
begin
|
|
192
|
-
response = connection.start do |http|
|
|
193
|
-
response = http.request(request)
|
|
194
|
-
|
|
195
|
-
if response.is_a?(Net::HTTPProxyAuthenticationRequired) && @proxy[:username] && @proxy[:password]
|
|
196
|
-
request = Net::HTTP::Post.new(url.request_uri)
|
|
197
|
-
request['User-Agent'] = @user_agent
|
|
198
|
-
request.proxy_select_auth(@proxy[:username], @proxy[:password], response)
|
|
199
|
-
request.set_form_data(options[:params])
|
|
200
|
-
response = http.request(request)
|
|
201
|
-
end
|
|
202
|
-
if response.is_a?(Net::HTTPUnauthorized) && @username && @password
|
|
203
|
-
request = Net::HTTP::Post.new(url.request_uri)
|
|
204
|
-
request['User-Agent'] = @user_agent
|
|
205
|
-
request.select_auth( @username, @password, response)
|
|
206
|
-
request.set_form_data(options[:params])
|
|
207
|
-
response = http.request(request)
|
|
208
|
-
end
|
|
209
|
-
response
|
|
210
|
-
end
|
|
211
|
-
rescue Timeout::Error, Errno::ETIMEDOUT
|
|
212
|
-
raise ConnectionError.new('%s timed out' % url.to_s)
|
|
213
|
-
rescue SocketError => e
|
|
214
|
-
raise ConnectionError.new('%s (%s)' % [url.to_s, e.to_s])
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
# Handle response errors.
|
|
218
|
-
if response.is_a? Net::HTTPBadRequest # 400
|
|
219
|
-
raise RequestError.new(url.to_s)
|
|
220
|
-
elsif response.is_a? Net::HTTPUnauthorized # 401
|
|
221
|
-
raise AuthenticationError.new(url.to_s)
|
|
222
|
-
elsif response.is_a? Net::HTTPNotFound # 404
|
|
223
|
-
raise ResourceNotFoundError.new(url.to_s)
|
|
224
|
-
elsif response.is_a? Net::HTTPForbidden
|
|
225
|
-
raise AuthenticationError.new(url.to_s)
|
|
226
|
-
elsif not response.is_a? Net::HTTPSuccess
|
|
227
|
-
raise ConnectionError.new(response.class.name)
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
return ::StringIO.new(response.body)
|
|
127
|
+
uri = create_uri(entity_type, options)
|
|
128
|
+
response = open_connection_and_make_request(uri, :post, options[:params])
|
|
129
|
+
return response
|
|
231
130
|
end
|
|
232
131
|
|
|
233
132
|
private # ----------------------------------------------------------------
|
|
234
133
|
|
|
134
|
+
def set_proxy_options(options)
|
|
135
|
+
@proxy = {}
|
|
136
|
+
unless options[:proxy].nil?
|
|
137
|
+
uri = URI.parse( options[:proxy] )
|
|
138
|
+
@proxy[:host], @proxy[:port] = uri.host, uri.port
|
|
139
|
+
if uri.userinfo
|
|
140
|
+
@proxy[:username], @proxy[:password] = uri.userinfo.split(/:/)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
235
145
|
# Builds a request URI for querying the webservice.
|
|
236
|
-
def create_uri(entity_type, options = {:id=>nil, :include=>nil, :filter=>nil, :version=>1, :type=>
|
|
146
|
+
def create_uri(entity_type, options = {:id=>nil, :include=>nil, :filter=>nil, :version=>1, :type=>'xml'})
|
|
237
147
|
# Make sure the version is set
|
|
238
148
|
options[:version] = 1 if options[:version].nil?
|
|
239
149
|
options[:type] = 'xml' if options[:type].nil?
|
|
240
|
-
|
|
241
|
-
|
|
150
|
+
uri = build_uri_without_querystring(entity_type, options)
|
|
151
|
+
uri = append_querystring_to_uri(uri, options)
|
|
152
|
+
return URI.parse(uri)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def build_uri_without_querystring(entity_type, options)
|
|
242
156
|
if options[:id]
|
|
243
157
|
# Make sure the id is a MBID object
|
|
244
158
|
id = options[:id]
|
|
@@ -252,14 +166,88 @@ module MusicBrainz
|
|
|
252
166
|
uri = 'http://%s:%d%s/%d/%s/' %
|
|
253
167
|
[@host, @port, @path_prefix, options[:version], entity_type]
|
|
254
168
|
end
|
|
255
|
-
|
|
256
|
-
|
|
169
|
+
return uri
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def append_querystring_to_uri(uri, options)
|
|
257
173
|
querystring = []
|
|
258
174
|
querystring << 'type=' + CGI.escape(options[:type]) unless options[:type].nil?
|
|
259
175
|
querystring << options[:include].to_s unless options[:include].nil?
|
|
260
176
|
querystring << options[:filter].to_s unless options[:filter].nil?
|
|
261
177
|
uri += '?' + querystring.join('&') unless querystring.empty?
|
|
262
|
-
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def open_connection_and_make_request(uri, request_type, form_data=nil)
|
|
181
|
+
connection = create_connection(uri)
|
|
182
|
+
response = make_request(connection, uri, request_type, form_data)
|
|
183
|
+
handle_response_errors(uri, response)
|
|
184
|
+
return ::StringIO.new(response.body)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def create_connection(uri)
|
|
188
|
+
connection = Net::HTTP.new(uri.host, uri.port, @proxy[:host], @proxy[:port])
|
|
189
|
+
set_connection_timeouts(connection)
|
|
190
|
+
return connection
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def make_request(connection, uri, request_type, form_data=nil)
|
|
194
|
+
response = nil
|
|
195
|
+
begin
|
|
196
|
+
connection.start do |http|
|
|
197
|
+
request = create_request(uri, request_type, form_data)
|
|
198
|
+
response = http.request(request)
|
|
199
|
+
if response.is_a?(Net::HTTPProxyAuthenticationRequired) && @proxy[:username] && @proxy[:password]
|
|
200
|
+
request = create_request(uri, request_type, form_data)
|
|
201
|
+
request.proxy_select_auth(@proxy[:username], @proxy[:password], response)
|
|
202
|
+
response = http.request(request)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
if response.is_a?(Net::HTTPUnauthorized) && @username && @password
|
|
206
|
+
request = create_request(uri, request_type, form_data)
|
|
207
|
+
request.select_auth @username, @password, response
|
|
208
|
+
response = http.request(request)
|
|
209
|
+
end
|
|
210
|
+
response
|
|
211
|
+
end
|
|
212
|
+
rescue Timeout::Error, Errno::ETIMEDOUT
|
|
213
|
+
raise ConnectionError.new('%s timed out' % uri.to_s)
|
|
214
|
+
rescue SocketError => e
|
|
215
|
+
raise ConnectionError.new('%s (%s)' % [uri.to_s, e.to_s])
|
|
216
|
+
rescue ::Exception => e
|
|
217
|
+
raise ConnectionError.new(e.to_s)
|
|
218
|
+
end
|
|
219
|
+
return response
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def set_connection_timeouts(connection)
|
|
223
|
+
connection.open_timeout = @open_timeout if @open_timeout
|
|
224
|
+
connection.read_timeout = @read_timeout if @read_timeout
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def create_request(uri, request_type, form_data=nil)
|
|
228
|
+
if request_type == :post
|
|
229
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
|
230
|
+
else
|
|
231
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
232
|
+
end
|
|
233
|
+
request['User-Agent'] = @user_agent
|
|
234
|
+
request.set_form_data(form_data) unless form_data.nil?
|
|
235
|
+
return request
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Handles response errors and raises appropriate exceptions
|
|
239
|
+
def handle_response_errors(uri, response)
|
|
240
|
+
if response.is_a? Net::HTTPBadRequest # 400
|
|
241
|
+
raise RequestError.new(uri.to_s)
|
|
242
|
+
elsif response.is_a? Net::HTTPUnauthorized # 401
|
|
243
|
+
raise AuthenticationError.new(uri.to_s)
|
|
244
|
+
elsif response.is_a? Net::HTTPNotFound # 404
|
|
245
|
+
raise ResourceNotFoundError.new(uri.to_s)
|
|
246
|
+
elsif response.is_a? Net::HTTPForbidden
|
|
247
|
+
raise AuthenticationError.new(uri.to_s)
|
|
248
|
+
elsif not response.is_a? Net::HTTPSuccess
|
|
249
|
+
raise ConnectionError.new(response.class.name)
|
|
250
|
+
end
|
|
263
251
|
end
|
|
264
252
|
|
|
265
253
|
end
|