rbrainz 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|