musicbrainz 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ coverage
2
+ rdoc
3
+ doc
4
+ .yardoc
5
+ .bundle
6
+ pkg
7
+ tmp
8
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile CHANGED
@@ -1,15 +1,2 @@
1
- source "http://rubygems.org"
2
-
3
- group :development do
4
- gem "bundler", "~> 1.0.0"
5
- gem "jeweler", "~> 1.6.4"
6
- gem "rcov", ">= 0"
7
- gem "rdoc", ">= 0"
8
- gem "shoulda"
9
-
10
- gem "rspec"
11
- gem "vcr"
12
- gem "webmock"
13
- end
14
-
15
- gem "nokogiri", ">= 0"
1
+ source :rubygems
2
+ gemspec
@@ -1,4 +1,6 @@
1
- Copyright (c) 2011 magnolia-fan
1
+ Copyright (c) 2012 Gregory Eremin
2
+
3
+ MIT License
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
@@ -17,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ ## MusicBrainz Web Service wrapper [![Travis CI](https://secure.travis-ci.org/magnolia-fan/musicbrainz.png)](http://travis-ci.org/magnolia-fan/musicbrainz)
2
+
3
+ ### Installation
4
+ ```bash
5
+ gem install musicbrainz
6
+ ```
7
+ ### Usage
8
+ ```ruby
9
+ require 'musicbrainz'
10
+
11
+ # Search for artists
12
+ @suggestions = MusicBrainz::Artist.search('Jet')
13
+
14
+ # Find artist by name or mbid
15
+ @foo_fighters = MusicBrainz::Artist.find_by_name('Foo Fighters')
16
+ @kasabian = MusicBrainz::Artist.find('69b39eab-6577-46a4-a9f5-817839092033')
17
+
18
+ # Use them like ActiveRecord models
19
+ @empire_tracks = @kasabian.release_groups[8].releases.first.tracks
20
+
21
+ # Setting a cache path enables caching of requests
22
+ MusicBrainz::Tools::Cache.cache_path = "tmp/cache"
23
+
24
+ # Configuring request interval
25
+ MusicBrainz::Tools::Proxy.query_interval = 1.2 # seconds
26
+ ```
27
+
28
+ ### Api
29
+
30
+ MusicBrainz::Artist
31
+ ```ruby
32
+ @artists = MusicBrainz::Artist.search(query)
33
+ @artist = MusicBrainz::Artist.find_by_name(name)
34
+ @artist = MusicBrainz::Artist.find(mbid)
35
+ @artist.id
36
+ @artist.type
37
+ @artist.name
38
+ @artist.country
39
+ @artist.date_begin
40
+ @artist.date_end
41
+ @artist.release_groups
42
+ ```
43
+
44
+ MusicBrainz::ReleaseGroup
45
+ ```ruby
46
+ @release_group = MusicBrainz::ReleaseGroup.find(mbid)
47
+ @release_group.id
48
+ @release_group.type
49
+ @release_group.title
50
+ @release_group.first_release_date
51
+ @release_group.releases
52
+ ```
53
+
54
+ MusicBrainz::Release
55
+ ```ruby
56
+ @release = MusicBrainz::Release.find(mbid)
57
+ @release.id
58
+ @release.title
59
+ @release.status
60
+ @release.date
61
+ @release.country
62
+ @release.tracks
63
+ ```
64
+
65
+ MusicBrainz::Track
66
+ ```ruby
67
+ @track = MusicBrainz::Track.find(mbid)
68
+ @track.position
69
+ @track.recording_id
70
+ @track.title
71
+ @track.length
72
+ ```
73
+
74
+ ### Contributing
75
+
76
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
77
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
78
+ * Fork the project
79
+ * Start a feature/bugfix branch
80
+ * Commit and push until you are happy with your contribution
81
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
82
+ * 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.
83
+
84
+ ### Copyright
85
+
86
+ Copyright (c) 2011 Gregory Eremin. See [LICENSE](https://raw.github.com/magnolia-fan/musicbrainz/master/LICENSE) for further details.
data/Rakefile CHANGED
@@ -1,53 +1,8 @@
1
- # encoding: utf-8
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
2
4
 
3
- require 'rubygems'
4
- require 'bundler'
5
- begin
6
- Bundler.setup(:default, :development)
7
- rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
10
- exit e.status_code
11
- end
12
- require 'rake'
5
+ RSpec::Core::RakeTask.new("spec")
13
6
 
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |gem|
16
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
- gem.name = "musicbrainz"
18
- gem.homepage = "http://github.com/magnolia-fan/musicbrainz"
19
- gem.license = "MIT"
20
- gem.summary = %Q{MusicBrainz Web Service wrapper}
21
- gem.description = %Q{MusicBrainz Web Service wrapper with ActiveRecord-style models}
22
- gem.email = "magnolia_fan@me.com"
23
- gem.authors = ["Gregory Eremin"]
24
- # dependencies defined in Gemfile
25
- end
26
- Jeweler::RubygemsDotOrgTasks.new
27
-
28
- require 'rake/testtask'
29
- Rake::TestTask.new(:test) do |test|
30
- test.libs << 'lib' << 'test'
31
- test.pattern = 'test/**/test_*.rb'
32
- test.verbose = true
33
- end
34
-
35
- require 'rcov/rcovtask'
36
- Rcov::RcovTask.new do |test|
37
- test.libs << 'test'
38
- test.pattern = 'test/**/test_*.rb'
39
- test.verbose = true
40
- test.rcov_opts << '--exclude "gems/*"'
41
- end
42
-
43
- task :default => :test
44
-
45
- require 'rdoc/task'
46
- RDoc::Task.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
-
49
- rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "musicbrainz #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
53
- end
7
+ task :default => :spec
8
+ task :test => :spec
data/lib/deprecated.rb ADDED
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module MusicBrainz
3
+ def self.query_interval=(sec)
4
+ MusicBrainz::Tools::Proxy.query_interval = sec
5
+ puts "WARNING! MusicBrainz.query_interval is deprecated. Use MusicBrainz::Tools::Proxy.query_interval"
6
+ end
7
+
8
+ def self.cache_path=(path)
9
+ MusicBrainz::Tools::Cache.cache_path = path
10
+ puts "WARNING! MusicBrainz.cache_path is deprecated. Use MusicBrainz::Tools::Cache.cache_path"
11
+ end
12
+ end
data/lib/musicbrainz.rb CHANGED
@@ -1,11 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  require "open-uri"
2
3
  require "socket"
3
4
  require "nokogiri"
4
5
  require "cgi"
5
6
 
6
- require "models/music_brainz"
7
- require "models/music_brainz/base"
8
- require "models/music_brainz/artist"
9
- require "models/music_brainz/release_group"
10
- require "models/music_brainz/release"
11
- require "models/music_brainz/track"
7
+ require "version"
8
+
9
+ module MusicBrainz
10
+ autoload :Base, "musicbrainz/base"
11
+ autoload :Artist, "musicbrainz/artist"
12
+ autoload :ReleaseGroup, "musicbrainz/release_group"
13
+ autoload :Release, "musicbrainz/release"
14
+ autoload :Track, "musicbrainz/track"
15
+
16
+ module Tools
17
+ autoload :Cache, "tools/cache"
18
+ autoload :Proxy, "tools/proxy"
19
+ end
20
+ end
@@ -1,26 +1,26 @@
1
- # encoding: UTF-8
1
+ # -*- encoding: utf-8 -*-
2
2
 
3
3
  module MusicBrainz
4
4
  class Artist < MusicBrainz::Base
5
5
  attr_accessor :id, :type, :name, :country, :date_begin, :date_end, :urls
6
6
  @release_groups
7
-
7
+
8
8
  def release_groups
9
9
  if @release_groups.nil? and not self.id.nil?
10
10
  @release_groups = []
11
- Nokogiri::XML(MusicBrainz.load(:release_group, :artist => self.id)).css('release-group').each do |rg|
11
+ Nokogiri::XML(self.class.load(:release_group, :artist => self.id)).css('release-group').each do |rg|
12
12
  @release_groups << MusicBrainz::ReleaseGroup.parse_xml(rg)
13
13
  end
14
14
  end
15
15
  @release_groups.sort{ |a, b| a.first_release_date <=> b.first_release_date }
16
16
  end
17
-
17
+
18
18
  def self.find mbid
19
- res = MusicBrainz.load :artist, :id => mbid, :inc => [:url_rels]
19
+ res = self.load :artist, :id => mbid, :inc => [:url_rels]
20
20
  return nil if res.nil?
21
21
  @artist = self.parse_xml(Nokogiri::XML(res))
22
22
  end
23
-
23
+
24
24
  def self.parse_xml xml
25
25
  @artist = MusicBrainz::Artist.new
26
26
  @artist.id = self.safe_get_attr(xml, 'artist', 'id')
@@ -35,21 +35,21 @@ module MusicBrainz
35
35
  end
36
36
  @artist
37
37
  end
38
-
38
+
39
39
  def self.discography mbid
40
40
  artist = self.find(mbid)
41
41
  artist.release_groups.each {|rg| rg.releases.each {|r| r.tracks } }
42
42
  artist
43
43
  end
44
-
44
+
45
45
  def self.find_by_name name
46
46
  matches = self.search name
47
47
  matches.length.zero? ? nil : self.find(matches.first[:mbid])
48
48
  end
49
-
49
+
50
50
  def self.search name
51
51
  artists = []
52
- xml = Nokogiri::XML(MusicBrainz.load(:artist, :query => CGI.escape(name).gsub(/\!/, '\!') + '~', :limit => 50))
52
+ xml = Nokogiri::XML(self.load(:artist, :query => CGI.escape(name).gsub(/\!/, '\!') + '~', :limit => 50))
53
53
  xml.css('artist-list > artist').each do |a|
54
54
  artist = {
55
55
  :name => a.first_element_child.text.gsub(/[`’]/, "'"),
@@ -60,7 +60,13 @@ module MusicBrainz
60
60
  :mbid => self.safe_get_attr(a, nil, 'id')
61
61
  }
62
62
  aliases = a.css('alias-list > alias').map{ |item| item.text }
63
- if aliases.include? name
63
+ if artist[:name] == name
64
+ artist[:weight] += 100
65
+ elsif artist[:name].downcase == name.downcase
66
+ artist[:weight] += 50
67
+ elsif artist[:name].downcase.gsub(/\s/, '') == name.downcase.gsub(/\s/, '')
68
+ artist[:weight] += 25
69
+ elsif aliases.include? name
64
70
  artist[:weight] += 20
65
71
  elsif aliases.map{ |item| item.downcase }.include? name.downcase
66
72
  artist[:weight] += 10
@@ -1,12 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  module MusicBrainz
2
3
  class Base
3
- def self.safe_get_attr xml, path, name
4
+ def self.safe_get_attr(xml, path, name)
4
5
  node = path.nil? ? xml : (xml.css(path).first unless xml.css(path).empty?)
5
6
  node.attr(name) unless node.nil? or node.attr(name).nil?
6
7
  end
7
-
8
- def self.safe_get_value xml, path
8
+
9
+ def self.safe_get_value(xml, path)
9
10
  xml.css(path).first.text unless xml.css(path).empty?
10
11
  end
12
+
13
+ def self.load(*args)
14
+ MusicBrainz::Tools::Proxy.load(*args)
15
+ end
11
16
  end
12
17
  end
@@ -1,23 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  module MusicBrainz
2
3
  class Release < MusicBrainz::Base
3
4
  attr_accessor :id, :title, :status, :format, :date, :country
4
5
  @tracks
5
-
6
+
6
7
  def tracks
7
8
  if @tracks.nil? and not self.id.nil?
8
9
  @tracks = []
9
- Nokogiri::XML(MusicBrainz.load(:release, :id => self.id, :inc => [:recordings, :media], :limit => 100)).css('medium-list > medium > track-list > track').each do |r|
10
+ Nokogiri::XML(self.class.load(:release, :id => self.id, :inc => [:recordings, :media], :limit => 100)).css('medium-list > medium > track-list > track').each do |r|
10
11
  @tracks << MusicBrainz::Track.parse_xml(r)
11
12
  end
12
13
  end
13
14
  @tracks.sort{ |a, b| a.position <=> b.position }
14
15
  end
15
-
16
+
16
17
  def self.find mbid
17
- xml = Nokogiri::XML(MusicBrainz.load(:release, :id => mbid, :inc => [:media])).css('release').first
18
+ xml = Nokogiri::XML(self.load(:release, :id => mbid, :inc => [:media])).css('release').first
18
19
  self.parse_xml(xml) unless xml.nil?
19
20
  end
20
-
21
+
21
22
  def self.parse_xml xml
22
23
  @release = MusicBrainz::Release.new
23
24
  @release.id = self.safe_get_attr(xml, nil, 'id')
@@ -1,23 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  module MusicBrainz
2
3
  class ReleaseGroup < MusicBrainz::Base
3
4
  attr_accessor :id, :type, :title, :disambiguation, :first_release_date
4
5
  @releases
5
-
6
+
6
7
  def releases
7
8
  if @releases.nil? and not self.id.nil?
8
9
  @releases = []
9
- Nokogiri::XML(MusicBrainz.load(:release, :release_group => self.id, :inc => [:media], :limit => 100)).css('release').each do |r|
10
+ Nokogiri::XML(self.class.load(:release, :release_group => self.id, :inc => [:media], :limit => 100)).css('release').each do |r|
10
11
  @releases << MusicBrainz::Release.parse_xml(r)
11
12
  end
12
13
  end
13
14
  @releases.sort{ |a, b| a.date <=> b.date }
14
15
  end
15
-
16
+
16
17
  def self.find mbid
17
- xml = Nokogiri::XML(MusicBrainz.load(:release_group, :id => mbid)).css('release-group').first
18
+ xml = Nokogiri::XML(self.load(:release_group, :id => mbid)).css('release-group').first
18
19
  self.parse_xml(xml) unless xml.nil?
19
20
  end
20
-
21
+
21
22
  def self.parse_xml xml
22
23
  @release_group = MusicBrainz::ReleaseGroup.new
23
24
  @release_group.id = self.safe_get_attr(xml, nil, 'id')
@@ -1,12 +1,13 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  module MusicBrainz
2
3
  class Track < MusicBrainz::Base
3
4
  attr_accessor :position, :recording_id, :title, :length
4
-
5
+
5
6
  def self.find mbid
6
- xml = Nokogiri::XML(MusicBrainz.load(:recording, :id => mbid))
7
+ xml = Nokogiri::XML(self.load(:recording, :id => mbid))
7
8
  self.parse_xml(xml) unless xml.nil?
8
9
  end
9
-
10
+
10
11
  def self.parse_xml xml
11
12
  @track = MusicBrainz::Track.new
12
13
  @track.position = self.safe_get_value(xml, 'position').to_i
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module MusicBrainz
3
+ module Tools
4
+ class Cache
5
+ @@cache_path = nil
6
+
7
+ def self.cache_path=(path)
8
+ @@cache_path = path
9
+ end
10
+
11
+ def self.cache_path
12
+ @@cache_path
13
+ end
14
+
15
+ def self.clear_cache
16
+ FileUtils.rm_r(@@cache_path) if @@cache_path && File.exist?(@@cache_path)
17
+ end
18
+
19
+ def self.cache_contents(url)
20
+ response = nil
21
+ url_parts = url.split('/')
22
+ file_name = url_parts.pop
23
+ directory = url_parts.pop
24
+ file_path = @@cache_path ? "#{@@cache_path}/#{directory}/#{file_name}" : nil
25
+
26
+ if file_path && File.exist?(file_path)
27
+ response = File.open(file_path).gets
28
+ else
29
+ response = yield
30
+
31
+ unless response.nil? or file_path.nil?
32
+ FileUtils.mkdir_p file_path.split('/')[0..-2].join('/')
33
+ file = File.new(file_path, 'w')
34
+ file.puts(response.gets) # .force_encoding('UTF-8')
35
+ file.chmod(0755)
36
+ file.close
37
+ response.rewind
38
+ end
39
+ end
40
+
41
+ response
42
+ end
43
+ end
44
+ end
45
+ end