musicbrainz 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +1 -4
  2. data/.travis.yml +2 -2
  3. data/Contributors +1 -0
  4. data/README.md +91 -40
  5. data/lib/mb.rb +2 -0
  6. data/lib/musicbrainz.rb +27 -22
  7. data/lib/musicbrainz/bindings/artist.rb +23 -0
  8. data/lib/musicbrainz/bindings/artist_release_groups.rb +13 -0
  9. data/lib/musicbrainz/bindings/artist_search.rb +23 -0
  10. data/lib/musicbrainz/bindings/release.rb +28 -0
  11. data/lib/musicbrainz/bindings/release_group.rb +18 -0
  12. data/lib/musicbrainz/bindings/release_group_releases.rb +13 -0
  13. data/lib/musicbrainz/bindings/release_tracks.rb +13 -0
  14. data/lib/musicbrainz/bindings/track.rb +16 -0
  15. data/lib/musicbrainz/client.rb +72 -0
  16. data/lib/musicbrainz/client_modules/caching_proxy.rb +46 -0
  17. data/lib/musicbrainz/client_modules/failsafe_proxy.rb +38 -0
  18. data/lib/musicbrainz/client_modules/transparent_proxy.rb +12 -0
  19. data/lib/musicbrainz/configuration.rb +60 -0
  20. data/lib/musicbrainz/deprecated.rb +36 -0
  21. data/lib/musicbrainz/middleware.rb +23 -0
  22. data/lib/musicbrainz/models/artist.rb +47 -0
  23. data/lib/musicbrainz/models/base_model.rb +63 -0
  24. data/lib/musicbrainz/models/release.rb +27 -0
  25. data/lib/musicbrainz/models/release_group.rb +28 -0
  26. data/lib/musicbrainz/models/track.rb +17 -0
  27. data/lib/musicbrainz/version.rb +3 -0
  28. data/musicbrainz.gemspec +10 -12
  29. data/spec/bindings/release_spec.rb +43 -0
  30. data/spec/client_modules/cache_spec.rb +62 -0
  31. data/spec/deprecated/cache_config_spec.rb +32 -0
  32. data/spec/deprecated/proxy_config_spec.rb +32 -0
  33. data/spec/{requests → models}/artist_spec.rb +3 -9
  34. data/spec/{requests → models}/release_group_spec.rb +2 -2
  35. data/spec/{requests → models}/release_spec.rb +1 -1
  36. data/spec/{requests → models}/track_spec.rb +0 -0
  37. data/spec/spec_helper.rb +13 -7
  38. metadata +63 -58
  39. data/Rakefile +0 -13
  40. data/lib/deprecated.rb +0 -25
  41. data/lib/musicbrainz/artist.rb +0 -63
  42. data/lib/musicbrainz/base.rb +0 -71
  43. data/lib/musicbrainz/release.rb +0 -43
  44. data/lib/musicbrainz/release_group.rb +0 -41
  45. data/lib/musicbrainz/track.rb +0 -23
  46. data/lib/parsers/artist.rb +0 -47
  47. data/lib/parsers/base.rb +0 -41
  48. data/lib/parsers/release.rb +0 -28
  49. data/lib/parsers/release_group.rb +0 -27
  50. data/lib/parsers/track.rb +0 -18
  51. data/lib/tools/cache.rb +0 -48
  52. data/lib/tools/proxy.rb +0 -62
  53. data/lib/version.rb +0 -5
  54. data/spec/misc/deprecated_spec.rb +0 -38
  55. data/spec/tools/cache_spec.rb +0 -59
data/.gitignore CHANGED
@@ -1,8 +1,5 @@
1
1
  coverage
2
- rdoc
3
- doc
4
- .yardoc
5
2
  .bundle
6
- pkg
7
3
  tmp
8
4
  Gemfile.lock
5
+ .gem
data/.travis.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  rvm:
2
- - 1.8.7
3
2
  - 1.9.2
4
- - 1.9.3
3
+ - 1.9.3
4
+ script: "bundle exec rspec"
data/Contributors CHANGED
@@ -3,3 +3,4 @@ Huge thanks to that people for making this gem better!
3
3
  Applicat (https://github.com/Applicat)
4
4
  Jens Fahnenbruck (https://github.com/jigfox)
5
5
  Sander Nieuwenhuizen (https://github.com/munkius)
6
+ Savater Sebastien (https://github.com/blakink)
data/README.md CHANGED
@@ -1,17 +1,44 @@
1
1
  ## MusicBrainz Web Service wrapper [![Travis CI](https://secure.travis-ci.org/magnolia-fan/musicbrainz.png)](http://travis-ci.org/magnolia-fan/musicbrainz)
2
2
 
3
+ ### Ruby Version
4
+ **IMPORTANT!**
5
+
6
+ Ruby version 1.9+ required. No support for 1.8.7 anymore, if you still on 1.8 consider using gem [version 0.5.2](https://github.com/magnolia-fan/musicbrainz/tree/v0.5.2#musicbrainz-web-service-wrapper-) and bundle it like this:
7
+
8
+ ```ruby
9
+ gem 'musicbrainz', '0.5.2'
10
+ ```
11
+
3
12
  ### Installation
4
- ```bash
13
+ ```
5
14
  gem install musicbrainz
6
15
  ```
7
16
  or add this line to your Gemfile
8
17
  ```ruby
9
- gem "musicbrainz"
18
+ gem 'musicbrainz'
19
+ ```
20
+
21
+ ### Configuration
22
+ ```ruby
23
+ MusicBrainz.configure do |c|
24
+ # Application identity (required)
25
+ c.app_name = "My Music App"
26
+ c.app_version = "1.0"
27
+ c.contact = "support@mymusicapp.com"
28
+
29
+ # Cache config (optional)
30
+ c.cache_path = "/tmp/musicbrainz-cache"
31
+ c.perform_caching = true
32
+
33
+ # Querying config (optional)
34
+ c.query_interval = 1.2 # seconds
35
+ c.tries_limit = 2
36
+ end
10
37
  ```
11
38
 
12
39
  ### Usage
13
40
  ```ruby
14
- require "musicbrainz"
41
+ require 'musicbrainz'
15
42
 
16
43
  # Search for artists
17
44
  @suggestions = MusicBrainz::Artist.search("Jet")
@@ -22,68 +49,92 @@ require "musicbrainz"
22
49
 
23
50
  # Use them like ActiveRecord models
24
51
  @empire_tracks = @kasabian.release_groups[8].releases.first.tracks
25
-
26
- # Setting a cache path enables caching of requests
27
- MusicBrainz::Tools::Cache.cache_path = "tmp/cache"
28
-
29
- # Configuring request interval
30
- MusicBrainz::Tools::Proxy.query_interval = 1.2 # seconds
31
52
  ```
32
53
 
33
- ### Api
54
+ ### Models
34
55
 
35
56
  MusicBrainz::Artist
36
57
  ```ruby
37
- @artists = MusicBrainz::Artist.search(query)
38
- @artist = MusicBrainz::Artist.find_by_name(name)
39
- @artist = MusicBrainz::Artist.find(mbid)
40
- @artist.id
41
- @artist.type
42
- @artist.name
43
- @artist.country
44
- @artist.date_begin
45
- @artist.date_end
58
+ # Class Methods:
59
+ MusicBrainz::Artist.find(id)
60
+ MusicBrainz::Artist.find_by_name(name)
61
+ MusicBrainz::Artist.search(name)
62
+ MusicBrainz::Artist.discography(id)
63
+
64
+ # Instance Methods:
46
65
  @artist.release_groups
66
+
67
+ # Fields
68
+ {
69
+ :id => String,
70
+ :type => String,
71
+ :name => String,
72
+ :country => String,
73
+ :date_begin => Date,
74
+ :date_end => Date,
75
+ :urls => Hash
76
+ }
47
77
  ```
48
78
 
49
79
  MusicBrainz::ReleaseGroup
50
80
  ```ruby
51
- @release_group = MusicBrainz::ReleaseGroup.find(mbid)
52
- @release_group.id
53
- @release_group.type
54
- @release_group.title
55
- @release_group.first_release_date
81
+ # Class Methods
82
+ MusicBrainz::ReleaseGroup.find(id)
83
+
84
+ # Instance Methods
56
85
  @release_group.releases
86
+
87
+ # Fields
88
+ {
89
+ :id => String,
90
+ :type => String,
91
+ :title => String,
92
+ :desc => String,
93
+ :first_release_date => Date
94
+ }
57
95
  ```
58
96
 
59
97
  MusicBrainz::Release
60
98
  ```ruby
61
- @release = MusicBrainz::Release.find(mbid)
62
- @release.id
63
- @release.title
64
- @release.status
65
- @release.date
66
- @release.country
99
+ # Class Methods
100
+ MusicBrainz::Release.find(id)
101
+
102
+ # Instance Methods
67
103
  @release.tracks
104
+
105
+ # Fields
106
+ {
107
+ :id => String,
108
+ :title => String,
109
+ :status => String,
110
+ :format => String,
111
+ :date => Date,
112
+ :country => String
113
+ }
68
114
  ```
69
115
 
70
116
  MusicBrainz::Track
71
117
  ```ruby
72
- @track = MusicBrainz::Track.find(mbid)
73
- @track.position
74
- @track.recording_id
75
- @track.title
76
- @track.length
118
+ # Class Methods
119
+ MusicBrainz::Track.find(id)
120
+
121
+ # Fields
122
+ {
123
+ :position => Integer,
124
+ :recording_id => String,
125
+ :title => String,
126
+ :length => Integer
127
+ }
77
128
  ```
78
129
 
79
130
  ### Testing
80
- ```bash
81
- bundle rake spec
131
+ ```
132
+ bundle exec rspec
82
133
  ```
83
134
 
84
135
  ### Debug console
85
- ```bash
86
- bundle rake console
136
+ ```
137
+ bundle exec irb -r musicbrainz
87
138
  ```
88
139
 
89
140
  ### Contributing
@@ -91,7 +142,7 @@ bundle rake console
91
142
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
92
143
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
93
144
  * Fork the project
94
- * Start a feature/bugfix branch
145
+ * **Start a feature/bugfix branch (IMPORTANT)**
95
146
  * Commit and push until you are happy with your contribution
96
147
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
97
148
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
data/lib/mb.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "musicbrainz"
2
+ MB = MusicBrainz
data/lib/musicbrainz.rb CHANGED
@@ -1,29 +1,34 @@
1
- # -*- encoding: utf-8 -*-
1
+ require "digest/sha1"
2
+ require "fileutils"
2
3
 
3
- require "open-uri"
4
- require "socket"
4
+ require "faraday"
5
5
  require "nokogiri"
6
- require "cgi"
7
6
 
8
- module MusicBrainz
9
- module Tools; end
10
- module Parsers; end
11
- end
7
+ require "musicbrainz/version"
8
+ require "musicbrainz/deprecated"
9
+ require "musicbrainz/middleware"
10
+ require "musicbrainz/configuration"
12
11
 
13
- require "version"
14
- require "deprecated"
12
+ require "musicbrainz/client_modules/transparent_proxy"
13
+ require "musicbrainz/client_modules/failsafe_proxy"
14
+ require "musicbrainz/client_modules/caching_proxy"
15
+ require "musicbrainz/client"
15
16
 
16
- require "musicbrainz/base"
17
- require "musicbrainz/artist"
18
- require "musicbrainz/release_group"
19
- require "musicbrainz/release"
20
- require "musicbrainz/track"
17
+ require "musicbrainz/models/base_model"
18
+ require "musicbrainz/models/artist"
19
+ require "musicbrainz/models/release_group"
20
+ require "musicbrainz/models/release"
21
+ require "musicbrainz/models/track"
21
22
 
22
- require "tools/cache"
23
- require "tools/proxy"
23
+ require "musicbrainz/bindings/artist"
24
+ require "musicbrainz/bindings/artist_search"
25
+ require "musicbrainz/bindings/artist_release_groups"
26
+ require "musicbrainz/bindings/release_group"
27
+ require "musicbrainz/bindings/release_group_releases"
28
+ require "musicbrainz/bindings/release"
29
+ require "musicbrainz/bindings/release_tracks"
30
+ require "musicbrainz/bindings/track"
24
31
 
25
- require "parsers/base"
26
- require "parsers/artist"
27
- require "parsers/release_group"
28
- require "parsers/release"
29
- require "parsers/track"
32
+ module MusicBrainz
33
+ GH_PAGE_URL = "http://git.io/brainz"
34
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ module MusicBrainz
3
+ module Bindings
4
+ module Artist
5
+ def parse(xml)
6
+ xml = xml.xpath('./artist') unless xml.xpath('./artist').empty?
7
+ {
8
+ id: (xml.attribute('id').value rescue nil),
9
+ type: (xml.attribute('type').value rescue nil),
10
+ name: (xml.xpath('./name').text.gsub(/[`’]/, "'") rescue nil),
11
+ country: (xml.xpath('./country').text rescue nil),
12
+ date_begin: (xml.xpath('./life-span/begin').text rescue nil),
13
+ date_end: (xml.xpath('./life-span/end').text rescue nil),
14
+ urls: (Hash[xml.xpath('./relation-list[@target-type="url"]/relation').map{ |xml|
15
+ [xml.attribute('type').value.downcase.split(" ").join("_").to_sym, xml.xpath('./target').text]
16
+ }] rescue {})
17
+ }
18
+ end
19
+
20
+ extend self
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ module MusicBrainz
2
+ module Bindings
3
+ module ArtistReleaseGroups
4
+ def parse(xml)
5
+ xml.xpath('./release-group-list/release-group').map do |xml|
6
+ MusicBrainz::Bindings::ReleaseGroup.parse(xml)
7
+ end
8
+ end
9
+
10
+ extend self
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ module MusicBrainz
3
+ module Bindings
4
+ module ArtistSearch
5
+ def parse(xml)
6
+ xml.xpath('./artist-list/artist').map do |xml|
7
+ {
8
+ id: (xml.attribute('id').value rescue nil),
9
+ mbid: (xml.attribute('id').value rescue nil), # Old shit
10
+ name: (xml.xpath('./name').text.gsub(/[`’]/, "'") rescue nil),
11
+ sort_name: (xml.xpath('./sort-name').gsub(/[`’]/, "'") rescue nil),
12
+ type: (xml.attribute('type').value rescue nil),
13
+ score: (xml.attribute('score').value.to_i rescue nil),
14
+ desc: (xml.xpath('./disambiguation').value rescue nil),
15
+ aliases: (xml.xpath('./alias-list/alias').map{ |xml| xml.text } rescue [])
16
+ } rescue nil
17
+ end.delete_if{ |item| item.nil? }
18
+ end
19
+
20
+ extend self
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ module MusicBrainz
2
+ module Bindings
3
+ module Release
4
+ def parse(xml)
5
+ xml = xml.xpath('./release') unless xml.xpath('./release').empty?
6
+
7
+ hash = {
8
+ id: (xml.attribute('id').value rescue nil),
9
+ title: (xml.xpath('./title').text rescue nil),
10
+ status: (xml.xpath('./status').text rescue nil),
11
+ country: (xml.xpath('./country').text rescue nil),
12
+ date: (xml.xpath('./date').text rescue nil)
13
+ }
14
+
15
+ formats = (xml.xpath('./medium-list/medium/format') rescue []).map(&:text)
16
+
17
+ hash[:format] = formats.uniq.map do |format|
18
+ format_count = formats.select{|f| f == format}.length
19
+ format_count == 1 ? format : "#{format_count}x#{format}"
20
+ end.join(' + ')
21
+
22
+ hash
23
+ end
24
+
25
+ extend self
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ module MusicBrainz
2
+ module Bindings
3
+ module ReleaseGroup
4
+ def parse(xml)
5
+ xml = xml.xpath('./release-group') unless xml.xpath('./release-group').empty?
6
+ {
7
+ id: (xml.attribute('id').value rescue nil),
8
+ type: (xml.attribute('type').value rescue nil),
9
+ title: (xml.xpath('./title').text rescue nil),
10
+ desc: (xml.xpath('./disambiguation').text rescue nil),
11
+ first_release_date: (xml.xpath('./first-release-date').text rescue nil)
12
+ }
13
+ end
14
+
15
+ extend self
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module MusicBrainz
2
+ module Bindings
3
+ module ReleaseGroupReleases
4
+ def parse(xml)
5
+ xml.xpath('./release-list/release').map do |xml|
6
+ MusicBrainz::Bindings::Release.parse(xml)
7
+ end
8
+ end
9
+
10
+ extend self
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module MusicBrainz
2
+ module Bindings
3
+ module ReleaseTracks
4
+ def parse(xml)
5
+ xml.xpath('./release/medium-list/medium/track-list/track').map do |xml|
6
+ MusicBrainz::Bindings::Track.parse(xml)
7
+ end
8
+ end
9
+
10
+ extend self
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module MusicBrainz
2
+ module Bindings
3
+ module Track
4
+ def parse(xml)
5
+ {
6
+ position: (xml.xpath('./position').text rescue nil),
7
+ recording_id: (xml.xpath('./recording').attribute('id').value rescue nil),
8
+ title: (xml.xpath('./recording/title').text rescue nil),
9
+ length: (xml.xpath('./recording/length').text rescue nil)
10
+ }
11
+ end
12
+
13
+ extend self
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,72 @@
1
+ module MusicBrainz
2
+ class Client
3
+ include ClientModules::TransparentProxy
4
+ include ClientModules::FailsafeProxy
5
+ include ClientModules::CachingProxy
6
+
7
+ def http
8
+ @faraday ||= Faraday.new do |f|
9
+ f.request :url_encoded # form-encode POST params
10
+ f.adapter Faraday.default_adapter # make requests with Net::HTTP
11
+ f.use MusicBrainz::Middleware # run requests with correct headers
12
+ end
13
+ end
14
+
15
+ def load(resource, query, params)
16
+ raise Exception.new("You need to run MusicBrainz.configure before querying") if MusicBrainz.config.nil?
17
+
18
+ url = build_url(resource, query)
19
+ response = get_contents(url)
20
+
21
+ return nil if response[:status] != 200
22
+
23
+ xml = Nokogiri::XML.parse(response[:body]).remove_namespaces!.xpath('/metadata')
24
+ data = binding_class_for(params[:binding]).parse(xml)
25
+
26
+ if params[:create_model]
27
+ model_class_for(params[:create_model]).new(data)
28
+ elsif params[:create_models]
29
+ models = data.map{ |item| model_class_for(params[:create_models]).new(item) }
30
+ models.sort!{ |a, b| a.send(params[:sort]) <=> b.send(params[:sort]) } if params[:sort]
31
+ models
32
+ else
33
+ data
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def build_url(resource, params)
40
+ "#{MusicBrainz.config.web_service_url}#{resource.to_s.gsub('_', '-')}" <<
41
+ ((id = params.delete(:id)) ? "/#{id}?" : "?") <<
42
+ params.map do |key, value|
43
+ key = key.to_s.gsub('_', '-')
44
+ value = if value.is_a?(Array)
45
+ value.map{ |el| el.to_s.gsub('_', '-') }.join(?+)
46
+ else
47
+ value.to_s
48
+ end
49
+ [key, value].join(?=)
50
+ end.join(?&)
51
+ end
52
+
53
+ def binding_class_for(key)
54
+ MusicBrainz::Bindings.const_get(constantized(key))
55
+ end
56
+
57
+ def model_class_for(key)
58
+ MusicBrainz.const_get(constantized(key))
59
+ end
60
+
61
+ def constantized(key)
62
+ key.to_s.split(?_).map(&:capitalize).join.to_sym
63
+ end
64
+ end
65
+
66
+ module ClientHelper
67
+ def client
68
+ @client ||= Client.new
69
+ end
70
+ end
71
+ extend ClientHelper
72
+ end