Mass rewrite
This commit is contained in:
parent
3bf68d152e
commit
7c42a90a6c
|
@ -1,8 +1,5 @@
|
|||
coverage
|
||||
rdoc
|
||||
doc
|
||||
.yardoc
|
||||
.bundle
|
||||
pkg
|
||||
tmp
|
||||
Gemfile.lock
|
||||
.gem
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
rvm:
|
||||
- 1.8.7
|
||||
- 1.9.2
|
||||
- 1.9.3
|
||||
- 1.9.3
|
||||
|
|
|
@ -3,3 +3,4 @@ Huge thanks to that people for making this gem better!
|
|||
Applicat (https://github.com/Applicat)
|
||||
Jens Fahnenbruck (https://github.com/jigfox)
|
||||
Sander Nieuwenhuizen (https://github.com/munkius)
|
||||
Savater Sebastien (https://github.com/blakink)
|
||||
|
|
13
Rakefile
13
Rakefile
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env rake
|
||||
require "bundler/gem_tasks"
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
RSpec::Core::RakeTask.new("spec")
|
||||
|
||||
task :default => :spec
|
||||
task :test => :spec
|
||||
|
||||
desc "Open an irb session preloaded with this library"
|
||||
task :console do
|
||||
sh "irb -rubygems -I lib -r musicbrainz.rb"
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
class << self
|
||||
def query_interval
|
||||
$stdout.send :puts, "WARNING! MusicBrainz.query_interval is deprecated. Use MusicBrainz::Tools::Proxy.query_interval"
|
||||
MusicBrainz::Tools::Proxy.query_interval
|
||||
end
|
||||
|
||||
def query_interval=(sec)
|
||||
$stdout.send :puts, "WARNING! MusicBrainz.query_interval= is deprecated. Use MusicBrainz::Tools::Proxy.query_interval"
|
||||
MusicBrainz::Tools::Proxy.query_interval = sec
|
||||
end
|
||||
|
||||
def cache_path
|
||||
$stdout.send :puts, "WARNING! MusicBrainz.cache_path is deprecated. Use MusicBrainz::Tools::Cache.cache_path"
|
||||
MusicBrainz::Tools::Cache.cache_path
|
||||
end
|
||||
|
||||
def cache_path=(path)
|
||||
$stdout.send :puts, "WARNING! MusicBrainz.cache_path= is deprecated. Use MusicBrainz::Tools::Cache.cache_path"
|
||||
MusicBrainz::Tools::Cache.cache_path = path
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,30 +1,34 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
require "digest/sha1"
|
||||
require "fileutils"
|
||||
|
||||
require "open-uri"
|
||||
require "socket"
|
||||
require "faraday"
|
||||
require "nokogiri"
|
||||
require "cgi"
|
||||
|
||||
require "musicbrainz/version"
|
||||
require "musicbrainz/deprecated"
|
||||
require "musicbrainz/middleware"
|
||||
require "musicbrainz/configuration"
|
||||
|
||||
require "musicbrainz/client_modules/transparent_proxy"
|
||||
require "musicbrainz/client_modules/failsafe_proxy"
|
||||
require "musicbrainz/client_modules/caching_proxy"
|
||||
require "musicbrainz/client"
|
||||
|
||||
require "musicbrainz/models/base_model"
|
||||
require "musicbrainz/models/artist"
|
||||
require "musicbrainz/models/release_group"
|
||||
require "musicbrainz/models/release"
|
||||
require "musicbrainz/models/track"
|
||||
|
||||
require "musicbrainz/bindings/artist"
|
||||
require "musicbrainz/bindings/artist_search"
|
||||
require "musicbrainz/bindings/artist_release_groups"
|
||||
require "musicbrainz/bindings/release_group"
|
||||
require "musicbrainz/bindings/release_group_releases"
|
||||
require "musicbrainz/bindings/release"
|
||||
require "musicbrainz/bindings/release_tracks"
|
||||
require "musicbrainz/bindings/track"
|
||||
|
||||
module MusicBrainz
|
||||
module Tools; end
|
||||
module Parsers; end
|
||||
GH_PAGE_URL = "http://git.io/brainz"
|
||||
end
|
||||
|
||||
require "version"
|
||||
require "deprecated"
|
||||
|
||||
require "musicbrainz/base"
|
||||
require "musicbrainz/artist"
|
||||
require "musicbrainz/release_group"
|
||||
require "musicbrainz/release"
|
||||
require "musicbrainz/track"
|
||||
|
||||
require "tools/configuration"
|
||||
require "tools/cache"
|
||||
require "tools/proxy"
|
||||
|
||||
require "parsers/base"
|
||||
require "parsers/artist"
|
||||
require "parsers/release_group"
|
||||
require "parsers/release"
|
||||
require "parsers/track"
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
class Artist < Base
|
||||
|
||||
field :id, String
|
||||
field :type, String
|
||||
field :name, String
|
||||
field :country, String
|
||||
field :date_begin, Time
|
||||
field :date_end, Time
|
||||
field :urls, Hash
|
||||
|
||||
def release_groups
|
||||
@release_groups ||= nil
|
||||
if @release_groups.nil? and !id.nil?
|
||||
@release_groups = self.class.load({
|
||||
:parser => :artist_release_groups,
|
||||
:create_models => MusicBrainz::ReleaseGroup
|
||||
}, {
|
||||
:resource => :release_group,
|
||||
:artist => id
|
||||
})
|
||||
@release_groups.sort!{ |a, b| a.first_release_date <=> b.first_release_date }
|
||||
end
|
||||
@release_groups
|
||||
end
|
||||
|
||||
class << self
|
||||
def find(mbid)
|
||||
load({
|
||||
:parser => :artist_model,
|
||||
:create_model => MusicBrainz::Artist
|
||||
}, {
|
||||
:resource => :artist,
|
||||
:id => mbid,
|
||||
:inc => [:url_rels]
|
||||
})
|
||||
end
|
||||
|
||||
def search(name)
|
||||
load({
|
||||
:parser => :artist_search
|
||||
}, {
|
||||
:resource => :artist,
|
||||
:query => "artist:" << CGI.escape(name).gsub(/\!/, '\!'),
|
||||
:limit => 10
|
||||
})
|
||||
end
|
||||
|
||||
def discography(mbid)
|
||||
artist = find(mbid)
|
||||
artist.release_groups.each { |rg| rg.releases.each { |r| r.tracks } }
|
||||
artist
|
||||
end
|
||||
|
||||
def find_by_name(name)
|
||||
matches = search(name)
|
||||
matches.length.zero? ? nil : find(matches.first[:mbid])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,71 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
class Base
|
||||
class << self
|
||||
def field(name, type)
|
||||
@fields ||= {}
|
||||
@fields[name] = type
|
||||
|
||||
define_method(name) {
|
||||
instance_variable_get("@#{name}")
|
||||
}
|
||||
define_method("#{name}=") { |val|
|
||||
instance_variable_set("@#{name}", validate_type(val, type))
|
||||
}
|
||||
end
|
||||
|
||||
def load(params, query)
|
||||
parser = MusicBrainz::Parsers.get_by_name(params[:parser])
|
||||
xml = MusicBrainz::Tools::Proxy.query(query)
|
||||
result = parser[:const].send(parser[:method], Nokogiri::XML(xml))
|
||||
if params[:create_model]
|
||||
result_model = params[:create_model].new
|
||||
result.each { |field, value|
|
||||
result_model.send("#{field}=".to_sym, value)
|
||||
}
|
||||
result_model
|
||||
elsif params[:create_models]
|
||||
result_models = []
|
||||
result.each { |item|
|
||||
result_model = params[:create_models].new
|
||||
item.each { |field, value|
|
||||
result_model.send("#{field}=".to_sym, value)
|
||||
}
|
||||
result_models << result_model
|
||||
}
|
||||
result_models
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
self.class.instance_variable_get("@fields").each { |name, type|
|
||||
instance_variable_set("@#{name}", nil)
|
||||
}
|
||||
end
|
||||
|
||||
def validate_type(val, type)
|
||||
if type == Integer
|
||||
val.to_i
|
||||
elsif type == Float
|
||||
val.to_f
|
||||
elsif type == String
|
||||
val.to_s
|
||||
elsif type == Time
|
||||
if val.nil? or val == ""
|
||||
val = "2030-12-31"
|
||||
elsif val.split("-").length == 1
|
||||
val << "-12-31"
|
||||
elsif val.split("-").length == 2
|
||||
val << "-31"
|
||||
end
|
||||
Time.utc(*val.split("-"))
|
||||
else
|
||||
val
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
# encoding: UTF-8
|
||||
module MusicBrainz
|
||||
module Bindings
|
||||
module Artist
|
||||
def parse(xml)
|
||||
xml = xml.xpath('./artist') unless xml.xpath('./artist').empty?
|
||||
{
|
||||
id: (xml.attribute('id').value rescue nil),
|
||||
type: (xml.attribute('type').value rescue nil),
|
||||
name: (xml.xpath('./name').text.gsub(/[`’]/, "'") rescue nil),
|
||||
country: (xml.xpath('./country').text rescue nil),
|
||||
date_begin: (xml.xpath('./life-span/begin').text rescue nil),
|
||||
date_end: (xml.xpath('./life-span/end').text rescue nil),
|
||||
urls: (Hash[xml.xpath('./relation-list[@target-type="url"]/relation').map{ |xml|
|
||||
[xml.attribute('type').value.downcase.split(" ").join("_").to_sym, xml.xpath('./target').text]
|
||||
}] rescue {})
|
||||
}
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module MusicBrainz
|
||||
module Bindings
|
||||
module ArtistReleaseGroups
|
||||
def parse(xml)
|
||||
xml.xpath('./release-group-list/release-group').map do |xml|
|
||||
MusicBrainz::Bindings::ReleaseGroup.parse(xml)
|
||||
end
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
# encoding: UTF-8
|
||||
module MusicBrainz
|
||||
module Bindings
|
||||
module ArtistSearch
|
||||
def parse(xml)
|
||||
xml.xpath('./artist-list/artist').map do |xml|
|
||||
{
|
||||
id: (xml.attribute('id').value rescue nil),
|
||||
mbid: (xml.attribute('id').value rescue nil), # Old shit
|
||||
name: (xml.xpath('./name').text.gsub(/[`’]/, "'") rescue nil),
|
||||
sort_name: (xml.xpath('./sort-name').gsub(/[`’]/, "'") rescue nil),
|
||||
type: (xml.attribute('type').value rescue nil),
|
||||
score: (xml.attribute('score').value.to_i rescue nil),
|
||||
desc: (xml.xpath('./disambiguation').value rescue nil),
|
||||
aliases: (xml.xpath('./alias-list/alias').map{ |xml| xml.text } rescue [])
|
||||
} rescue nil
|
||||
end.delete_if{ |item| item.nil? }
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
module MusicBrainz
|
||||
module Bindings
|
||||
module Release
|
||||
def parse(xml)
|
||||
xml = xml.xpath('./release') unless xml.xpath('./release').empty?
|
||||
{
|
||||
id: (xml.attribute('id').value rescue nil),
|
||||
title: (xml.xpath('./title').text rescue nil),
|
||||
status: (xml.xpath('./status').text rescue nil),
|
||||
country: (xml.xpath('./country').text rescue nil),
|
||||
format: (xml.xpath('./medium-list/medium/format').text rescue nil),
|
||||
date: (xml.xpath('./date').text rescue nil)
|
||||
}
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
module MusicBrainz
|
||||
module Bindings
|
||||
module ReleaseGroup
|
||||
def parse(xml)
|
||||
xml = xml.xpath('./release-group') unless xml.xpath('./release-group').empty?
|
||||
{
|
||||
id: (xml.attribute('id').value rescue nil),
|
||||
type: (xml.attribute('type').value rescue nil),
|
||||
title: (xml.xpath('./title').text rescue nil),
|
||||
desc: (xml.xpath('./disambiguation').text rescue nil),
|
||||
first_release_date: (xml.xpath('./first-release-date').text rescue nil)
|
||||
}
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module MusicBrainz
|
||||
module Bindings
|
||||
module ReleaseGroupReleases
|
||||
def parse(xml)
|
||||
xml.xpath('./release-list/release').map do |xml|
|
||||
MusicBrainz::Bindings::Release.parse(xml)
|
||||
end
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module MusicBrainz
|
||||
module Bindings
|
||||
module ReleaseTracks
|
||||
def parse(xml)
|
||||
xml.xpath('./release/medium-list/medium/track-list/track').map do |xml|
|
||||
MusicBrainz::Bindings::Track.parse(xml)
|
||||
end
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
module MusicBrainz
|
||||
module Bindings
|
||||
module Track
|
||||
def parse(xml)
|
||||
{
|
||||
position: (xml.xpath('./position').text rescue nil),
|
||||
recording_id: (xml.xpath('./recording').attribute('id').value rescue nil),
|
||||
title: (xml.xpath('./recording/title').text rescue nil),
|
||||
length: (xml.xpath('./recording/length').text rescue nil)
|
||||
}
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
module MusicBrainz
|
||||
module Client
|
||||
def http
|
||||
@faraday ||= Faraday.new do |f|
|
||||
f.request :url_encoded # form-encode POST params
|
||||
f.adapter Faraday.default_adapter # make requests with Net::HTTP
|
||||
f.use MusicBrainz::Middleware # run requests with correct headers
|
||||
end
|
||||
end
|
||||
|
||||
def load(resource, query, params)
|
||||
response = contents_of(build_url(resource, query))
|
||||
xml = Nokogiri::XML.parse(response).remove_namespaces!.xpath('/metadata')
|
||||
data = params[:binding].parse(xml)
|
||||
|
||||
if params[:create_model]
|
||||
result_model = params[:create_model].new
|
||||
data.each do |field, value|
|
||||
result_model.send("#{field}=".to_sym, value)
|
||||
end
|
||||
result_model
|
||||
elsif params[:create_models]
|
||||
result_models = []
|
||||
data.each do |item|
|
||||
result_model = params[:create_models].new
|
||||
item.each do |field, value|
|
||||
result_model.send("#{field}=".to_sym, value)
|
||||
end
|
||||
result_models << result_model
|
||||
end
|
||||
if params[:sort]
|
||||
result_models.sort!{ |a, b| a.send(params[:sort]) <=> b.send(params[:sort]) }
|
||||
end
|
||||
result_models
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
def contents_of(url)
|
||||
if method_defined? :get_contents
|
||||
get_contents url
|
||||
else
|
||||
http.get url
|
||||
end
|
||||
end
|
||||
|
||||
def build_url(resource, params)
|
||||
"#{MusicBrainz.config.web_service_url}#{resource.to_s.gsub('_', '-')}" <<
|
||||
((id = params.delete(:id)) ? "/#{id}?" : "?") <<
|
||||
params.map do |key, value|
|
||||
key = key.to_s.gsub('_', '-')
|
||||
value = if value.is_a?(Array)
|
||||
value.map{ |el| el.to_s.gsub('_', '-') }.join('+')
|
||||
else
|
||||
value.to_s
|
||||
end
|
||||
"#{key}=#{value}"
|
||||
end.join('&')
|
||||
end
|
||||
|
||||
include ClientModules::TransparentProxy
|
||||
include ClientModules::FailsafeProxy
|
||||
include ClientModules::CachingProxy
|
||||
extend self
|
||||
end
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
module MusicBrainz
|
||||
module ClientModules
|
||||
module CachingProxy
|
||||
def cache_path
|
||||
MusicBrainz.config.cache_path
|
||||
end
|
||||
|
||||
def clear_cache
|
||||
FileUtils.rm_r(cache_path) if cache_path && File.exist?(cache_path)
|
||||
end
|
||||
|
||||
def get_contents(url)
|
||||
return super unless MusicBrainz.config.perform_caching
|
||||
|
||||
token = Digest::SHA256.hexdigest(url)
|
||||
file_path = "#{cache_path}/#{token[0..1]}/#{token[2..3]}/#{token[4..-1]}.xml"
|
||||
|
||||
response = nil
|
||||
|
||||
if File.exist?(file_path)
|
||||
response = File.open(file_path).gets
|
||||
else
|
||||
response = super
|
||||
unless response.nil? or response.empty?
|
||||
FileUtils.mkdir_p file_path.split('/')[0..-2].join('/')
|
||||
File.open(file_path, 'w') do |f|
|
||||
f.puts response
|
||||
f.chmod 0755
|
||||
f.close
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
module MusicBrainz
|
||||
module ClientModules
|
||||
module FailsafeProxy
|
||||
def get_contents(url)
|
||||
response = nil
|
||||
|
||||
MusicBrainz.config.tries_limit.times do
|
||||
time_passed = Time.now.to_f - @last_query_time ||= 0.0
|
||||
if time_passed < MusicBrainz.config.query_interval
|
||||
sleep(MusicBrainz.config.query_interval - time_passed)
|
||||
end
|
||||
|
||||
response = super
|
||||
@last_query_time = Time.now.to_f
|
||||
|
||||
break if response.status == 200
|
||||
end
|
||||
|
||||
response.body rescue nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
module MusicBrainz
|
||||
module ClientModules
|
||||
module TransparentProxy
|
||||
def get_contents(url)
|
||||
http.get url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
module MusicBrainz
|
||||
class Configuration
|
||||
attr_accessor :app_name, :app_version, :contact,
|
||||
:web_service_url,
|
||||
:query_interval, :tries_limit,
|
||||
:cache_path, :perform_caching
|
||||
|
||||
DEFAULT_WEB_SERVICE_URL = "http://musicbrainz.org/ws/2/"
|
||||
DEFAULT_QUERY_INTERVAL = 1.5
|
||||
DEFAULT_TRIES_LIMIT = 5
|
||||
DEFAULT_CACHE_PATH = File.join(File.dirname(__FILE__), "..", "tmp", "cache")
|
||||
DEFAULT_PERFORM_CACHING = false
|
||||
|
||||
def initialize
|
||||
@web_service_url = DEFAULT_WEB_SERVICE_URL
|
||||
@query_interval = DEFAULT_QUERY_INTERVAL
|
||||
@tries_limit = DEFAULT_TRIES_LIMIT
|
||||
@cache_path = DEFAULT_CACHE_PATH
|
||||
@perform_caching = DEFAULT_PERFORM_CACHING
|
||||
end
|
||||
|
||||
def user_agent_string
|
||||
%w[ app_name app_version contact ].each do |param|
|
||||
raise "#{param} must be set" if instance_variable_get("@#{param}").nil?
|
||||
end
|
||||
|
||||
"#{@app_name}/#{@app_version} ( #{@contact} )"
|
||||
end
|
||||
end
|
||||
|
||||
module Configurable
|
||||
def configure
|
||||
raise "Configuration missing" unless block_given?
|
||||
yield @config ||= MusicBrainz::Configuration.new
|
||||
end
|
||||
|
||||
def config
|
||||
@config
|
||||
end
|
||||
end
|
||||
extend Configurable
|
||||
end
|
|
@ -0,0 +1,45 @@
|
|||
module MusicBrainz
|
||||
def query_interval
|
||||
MusicBrainz.config.query_interval
|
||||
end
|
||||
|
||||
def query_interval=(value)
|
||||
MusicBrainz.config.query_interval = value
|
||||
end
|
||||
|
||||
def cache_path
|
||||
MusicBrainz.config.cache_path
|
||||
end
|
||||
|
||||
def cache_path=(value)
|
||||
MusicBrainz.config.cache_path = value
|
||||
end
|
||||
|
||||
module Tools
|
||||
module Proxy
|
||||
def query_interval
|
||||
MusicBrainz.config.query_interval
|
||||
end
|
||||
|
||||
def query_interval=(value)
|
||||
MusicBrainz.config.query_interval = value
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
|
||||
module Cache
|
||||
def cache_path
|
||||
MusicBrainz.config.cache_path
|
||||
end
|
||||
|
||||
def cache_path=(value)
|
||||
MusicBrainz.config.cache_path = value
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
||||
end
|
||||
|
||||
extend self
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
module MusicBrainz
|
||||
class Middleware < Faraday::Middleware
|
||||
def call(env)
|
||||
env[:request_headers]["User-Agent"] = MusicBrainz.config.user_agent_string
|
||||
env[:request_headers]["Via"] = "gem musicbrainz/#{VERSION} (#{GH_PAGE_URL})"
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,51 @@
|
|||
module MusicBrainz
|
||||
class Artist
|
||||
include BaseModel
|
||||
|
||||
field :id, String
|
||||
field :type, String
|
||||
field :name, String
|
||||
field :country, String
|
||||
field :date_begin, Time
|
||||
field :date_end, Time
|
||||
field :urls, Hash
|
||||
|
||||
attr_writer :release_groups
|
||||
|
||||
def release_groups
|
||||
@release_groups ||= Client::load(:release_group, { artist: id }, {
|
||||
binding: MusicBrainz::Bindings::ArtistReleaseGroups,
|
||||
create_models: MusicBrainz::ReleaseGroup,
|
||||
sort: :first_release_date
|
||||
}) unless @id.nil?
|
||||
end
|
||||
|
||||
class << self
|
||||
def find(id)
|
||||
Client.load(:artist, { id: id, inc: [:url_rels] }, {
|
||||
binding: MusicBrainz::Bindings::Artist,
|
||||
create_model: MusicBrainz::Artist
|
||||
})
|
||||
end
|
||||
|
||||
def search(name)
|
||||
name = CGI.escape(name).gsub(/\!/, '\!')
|
||||
|
||||
Client.load(:artist, { query: "artist:#{name}", limit: 10 }, {
|
||||
binding: MusicBrainz::Bindings::ArtistSearch
|
||||
})
|
||||
end
|
||||
|
||||
def discography(mbid)
|
||||
artist = find(mbid)
|
||||
artist.release_groups.each { |rg| rg.releases.each { |r| r.tracks } }
|
||||
artist
|
||||
end
|
||||
|
||||
def find_by_name(name)
|
||||
matches = search(name)
|
||||
matches.empty? ? nil : find(matches.first[:id])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
module MusicBrainz
|
||||
module BaseModel
|
||||
def self.included(klass)
|
||||
klass.send(:include, InstanceMethods)
|
||||
klass.send(:extend, ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def field(name, type)
|
||||
self.class_exec do
|
||||
attr_reader name
|
||||
|
||||
define_method("#{name}=") do |val|
|
||||
instance_variable_set("@#{name}", validate_type(val, type))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def validate_type(val, type)
|
||||
if type == Integer
|
||||
val.to_i
|
||||
elsif type == Float
|
||||
val.to_f
|
||||
elsif type == String
|
||||
val.to_s
|
||||
elsif type == Time
|
||||
if val.nil? or val == ""
|
||||
val = "2030-12-31"
|
||||
elsif val.split("-").length == 1
|
||||
val << "-12-31"
|
||||
elsif val.split("-").length == 2
|
||||
val << "-31"
|
||||
end
|
||||
Time.utc(*val.split("-"))
|
||||
else
|
||||
val
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
module MusicBrainz
|
||||
class Release
|
||||
include BaseModel
|
||||
|
||||
field :id, String
|
||||
field :title, String
|
||||
field :status, String
|
||||
field :format, String
|
||||
field :date, Time
|
||||
field :country, String
|
||||
|
||||
attr_writer :tracks
|
||||
|
||||
def tracks
|
||||
@tracks ||= Client::load(:release, { id: id, inc: [:recordings, :media], limit: 100 }, {
|
||||
binding: MusicBrainz::Bindings::ReleaseTracks,
|
||||
create_models: MusicBrainz::Track,
|
||||
sort: :position
|
||||
}) unless @id.nil?
|
||||
end
|
||||
|
||||
class << self
|
||||
def find(id)
|
||||
Client.load(:release, { id: id, inc: [:media] }, {
|
||||
binding: MusicBrainz::Bindings::Release,
|
||||
create_model: MusicBrainz::Release
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
module MusicBrainz
|
||||
class ReleaseGroup
|
||||
include BaseModel
|
||||
|
||||
field :id, String
|
||||
field :type, String
|
||||
field :title, String
|
||||
field :desc, String
|
||||
field :first_release_date, Time
|
||||
|
||||
alias_method :disambiguation, :desc
|
||||
attr_writer :releases
|
||||
|
||||
def releases
|
||||
@releases ||= Client::load(:release, { release_group: id, inc: [:media], limit: 100 }, {
|
||||
binding: MusicBrainz::Bindings::ReleaseGroupReleases,
|
||||
create_models: MusicBrainz::Release,
|
||||
sort: :date
|
||||
}) unless @id.nil?
|
||||
end
|
||||
|
||||
class << self
|
||||
def find(id)
|
||||
Client.load(:release_group, { id: id }, {
|
||||
binding: MusicBrainz::Bindings::ReleaseGroup,
|
||||
create_model: MusicBrainz::ReleaseGroup
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
module MusicBrainz
|
||||
class Track
|
||||
include BaseModel
|
||||
|
||||
field :position, Integer
|
||||
field :recording_id, String
|
||||
field :title, String
|
||||
field :length, Integer
|
||||
|
||||
class << self
|
||||
def find(id)
|
||||
Client.load(:recording, { id: id }, {
|
||||
binding: MusicBrainz::Bindings::Track,
|
||||
create_model: MusicBrainz::Track
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
class Release < Base
|
||||
|
||||
field :id, String
|
||||
field :title, String
|
||||
field :status, String
|
||||
field :format, String
|
||||
field :date, Time
|
||||
field :country, String
|
||||
|
||||
def tracks
|
||||
@tracks ||= nil
|
||||
if @tracks.nil? and !id.nil?
|
||||
@tracks = self.class.load({
|
||||
:parser => :release_tracks,
|
||||
:create_models => MusicBrainz::Track
|
||||
}, {
|
||||
:resource => :release,
|
||||
:id => id,
|
||||
:inc => [:recordings, :media],
|
||||
:limit => 100
|
||||
})
|
||||
@tracks.sort{ |a, b| a.position <=> b.position }
|
||||
end
|
||||
@tracks
|
||||
end
|
||||
|
||||
class << self
|
||||
def find(mbid)
|
||||
load({
|
||||
:parser => :release_model,
|
||||
:create_model => MusicBrainz::Release
|
||||
}, {
|
||||
:resource => :release,
|
||||
:id => mbid,
|
||||
:inc => [:media]
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
class ReleaseGroup < Base
|
||||
|
||||
field :id, String
|
||||
field :type, String
|
||||
field :title, String
|
||||
field :disambiguation, String
|
||||
field :first_release_date, Time
|
||||
|
||||
def releases
|
||||
@releases ||= nil
|
||||
if @releases.nil? and !id.nil?
|
||||
@releases = self.class.load({
|
||||
:parser => :release_group_releases,
|
||||
:create_models => MusicBrainz::Release
|
||||
}, {
|
||||
:resource => :release,
|
||||
:release_group => self.id,
|
||||
:inc => [:media],
|
||||
:limit => 100
|
||||
})
|
||||
@releases.sort!{ |a, b| a.date <=> b.date }
|
||||
end
|
||||
@releases
|
||||
end
|
||||
|
||||
class << self
|
||||
def find(mbid)
|
||||
load({
|
||||
:parser => :release_group_model,
|
||||
:create_model => MusicBrainz::ReleaseGroup
|
||||
}, {
|
||||
:resource => :release_group,
|
||||
:id => mbid
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
class Track < Base
|
||||
|
||||
field :position, Integer
|
||||
field :recording_id, String
|
||||
field :title, String
|
||||
field :length, Integer
|
||||
|
||||
class << self
|
||||
def find(mbid)
|
||||
load({
|
||||
:parser => :track_model,
|
||||
:create_model => MusicBrainz::Track
|
||||
}, {
|
||||
:resource => :recording,
|
||||
:id => mbid
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
module MusicBrainz
|
||||
VERSION = "0.8"
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Parsers
|
||||
class Artist < Base
|
||||
class << self
|
||||
def model(xml)
|
||||
res = {
|
||||
:id => safe_get_attr(xml, "artist", "id"),
|
||||
:type => safe_get_attr(xml, "artist", "type"),
|
||||
:name => safe_get_value(xml, "artist > name").gsub(/[`’]/, "'"),
|
||||
:country => safe_get_value(xml, "artist > country"),
|
||||
:date_begin => safe_get_value(xml, "artist > life-span > begin"),
|
||||
:date_end => safe_get_value(xml, "artist > life-span > end"),
|
||||
:urls => {}
|
||||
}
|
||||
xml.css("relation-list[target-type='url'] > relation").each { |rel|
|
||||
res[:urls][rel.attr("type").downcase.split(" ").join("_").to_sym] = rel.css("target").text
|
||||
}
|
||||
res
|
||||
end
|
||||
|
||||
def search(xml)
|
||||
xml.css("artist-list > artist").map do |a|
|
||||
{
|
||||
:name => a.first_element_child.text.gsub(/[`’]/, "'"),
|
||||
:sort_name => safe_get_value(a, "sort-name").gsub(/[`’]/, "'"),
|
||||
:score => (safe_get_attr(a, nil, "score").to_i rescue 0),
|
||||
:desc => safe_get_value(a, "disambiguation"),
|
||||
:type => safe_get_attr(a, nil, "type"),
|
||||
:mbid => safe_get_attr(a, nil, "id"),
|
||||
:aliases => a.css("alias-list > alias").map { |item| item.text }
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def release_groups(xml)
|
||||
release_groups = []
|
||||
xml.css("release-group").each do |rg|
|
||||
release_groups << MusicBrainz::Parsers::ReleaseGroup.model(rg)
|
||||
end
|
||||
release_groups
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,41 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Parsers
|
||||
class << self
|
||||
def get_by_name(name)
|
||||
case name
|
||||
when :artist_model
|
||||
{ :const => MusicBrainz::Parsers::Artist, :method => :model }
|
||||
when :artist_search
|
||||
{ :const => MusicBrainz::Parsers::Artist, :method => :search }
|
||||
when :artist_release_groups
|
||||
{ :const => MusicBrainz::Parsers::Artist, :method => :release_groups }
|
||||
when :release_group_model
|
||||
{ :const => MusicBrainz::Parsers::ReleaseGroup, :method => :model }
|
||||
when :release_group_releases
|
||||
{ :const => MusicBrainz::Parsers::ReleaseGroup, :method => :releases }
|
||||
when :release_model
|
||||
{ :const => MusicBrainz::Parsers::Release, :method => :model }
|
||||
when :release_tracks
|
||||
{ :const => MusicBrainz::Parsers::Release, :method => :tracks }
|
||||
when :track_model
|
||||
{ :const => MusicBrainz::Parsers::Track, :method => :model }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Base
|
||||
class << self
|
||||
def safe_get_attr(xml, path, name)
|
||||
node = path.nil? ? xml : (xml.css(path).first unless xml.css(path).empty?)
|
||||
node.attr(name) unless node.nil? or node.attr(name).nil?
|
||||
end
|
||||
|
||||
def safe_get_value(xml, path)
|
||||
xml.css(path).first.text unless xml.css(path).empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,28 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Parsers
|
||||
class Release < Base
|
||||
class << self
|
||||
def model(xml)
|
||||
{
|
||||
:id => safe_get_attr(xml, nil, "id") || safe_get_attr(xml, "release", "id"),
|
||||
:title => safe_get_value(xml, "title"),
|
||||
:status => safe_get_value(xml, "status"),
|
||||
:country => safe_get_value(xml, "country"),
|
||||
:format => safe_get_value(xml, "medium-list > medium > format"),
|
||||
:date => safe_get_value(xml, "date")
|
||||
}
|
||||
end
|
||||
|
||||
def tracks(xml)
|
||||
tracks = []
|
||||
xml.css("medium-list > medium > track-list > track").each do |r|
|
||||
tracks << MusicBrainz::Parsers::Track.model(r)
|
||||
end
|
||||
tracks
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,27 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Parsers
|
||||
class ReleaseGroup < Base
|
||||
class << self
|
||||
def model(xml)
|
||||
{
|
||||
:id => safe_get_attr(xml, nil, "id") || safe_get_attr(xml, "release-group", "id"),
|
||||
:type => safe_get_attr(xml, nil, "type") || safe_get_attr(xml, "release-group", "type"),
|
||||
:title => safe_get_value(xml, "title"),
|
||||
:disambiguation => safe_get_value(xml, "disambiguation"),
|
||||
:first_release_date => safe_get_value(xml, "first-release-date")
|
||||
}
|
||||
end
|
||||
|
||||
def releases(xml)
|
||||
releases = []
|
||||
xml.css("release").each do |r|
|
||||
releases << MusicBrainz::Parsers::Release.model(r)
|
||||
end
|
||||
releases
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Parsers
|
||||
class Track < Base
|
||||
class << self
|
||||
def model(xml)
|
||||
{
|
||||
:position => safe_get_value(xml, "position"),
|
||||
:recording_id => safe_get_attr(xml, "recording", "id"),
|
||||
:title => safe_get_value(xml, "recording > title"),
|
||||
:length => safe_get_value(xml, "length") || safe_get_value(xml, "recording > length")
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,48 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Tools
|
||||
class Cache
|
||||
class << self
|
||||
@@cache_path = nil
|
||||
|
||||
def cache_path=(path)
|
||||
@@cache_path = path
|
||||
end
|
||||
|
||||
def cache_path
|
||||
@@cache_path
|
||||
end
|
||||
|
||||
def clear_cache
|
||||
FileUtils.rm_r(@@cache_path) if @@cache_path && File.exist?(@@cache_path)
|
||||
end
|
||||
|
||||
def cache_contents(url)
|
||||
response = nil
|
||||
url_parts = url.split('/')
|
||||
file_name = url_parts.pop
|
||||
directory = url_parts.pop
|
||||
file_path = @@cache_path ? "#{@@cache_path}/#{directory}/#{file_name}" : nil
|
||||
|
||||
if file_path && File.exist?(file_path)
|
||||
response = File.open(file_path).gets
|
||||
else
|
||||
response = yield
|
||||
|
||||
unless response.nil? or file_path.nil?
|
||||
FileUtils.mkdir_p file_path.split('/')[0..-2].join('/')
|
||||
file = File.new(file_path, 'w')
|
||||
file.puts(response.gets) # .force_encoding('UTF-8')
|
||||
file.chmod(0755)
|
||||
file.close
|
||||
response.rewind
|
||||
end
|
||||
end
|
||||
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,54 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
|
||||
def self.configure
|
||||
yield @config ||= MusicBrainz::Tools::Configuration.new
|
||||
end
|
||||
|
||||
def self.config
|
||||
@config
|
||||
end
|
||||
|
||||
module Tools
|
||||
class Configuration
|
||||
def self.add_config name, value=nil
|
||||
self.instance_variable_set "@#{name}", value
|
||||
|
||||
class_eval <<-RUBY
|
||||
def #{name}=(value)
|
||||
@#{name} = value
|
||||
end
|
||||
|
||||
def #{name}
|
||||
@#{name} || self.class.instance_variable_get('@#{name}')
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
DEFAULT_USER_AGENT = "gem musicbrainz (https://github.com/magnolia-fan/musicbrainz) @ " + Socket.gethostname
|
||||
|
||||
add_config :application
|
||||
add_config :version
|
||||
add_config :contact
|
||||
|
||||
add_config :query_interval, 1.5
|
||||
add_config :tries_limit, 5
|
||||
|
||||
add_config :web_service_url, "http://musicbrainz.org/ws/2/"
|
||||
|
||||
def user_agent
|
||||
return @user_agent if @user_agent
|
||||
|
||||
if application
|
||||
@user_agent = application
|
||||
@user_agent << "/#{version}" if version
|
||||
@user_agent << " (#{contact})" if contact
|
||||
@user_agent << ' via '
|
||||
end
|
||||
|
||||
@user_agent = "#{@user_agent}#{DEFAULT_USER_AGENT}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,57 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
module Tools
|
||||
class Proxy
|
||||
class << self
|
||||
@@last_query_time = 0
|
||||
|
||||
def config
|
||||
MusicBrainz.config
|
||||
end
|
||||
|
||||
def query_interval=(sec)
|
||||
config.query_interval = sec.to_f
|
||||
end
|
||||
|
||||
def tries_limit=(num)
|
||||
config.tries_limit = num.to_i
|
||||
end
|
||||
|
||||
def query(params = {})
|
||||
url = config.web_service_url + params[:resource].to_s.gsub('_', '-') + '/' + (params[:id].to_s || '')
|
||||
params.delete(:resource)
|
||||
params.delete(:id) unless params[:id].nil?
|
||||
url << '?' + params.map{ |k, v|
|
||||
k = k.to_s.gsub('_', '-')
|
||||
v = (v.is_a?(Array) ? v.map{ |_| _.to_s.gsub('_', '-') }.join('+') : v.to_s)
|
||||
k + '=' + v
|
||||
}.join('&') unless params.empty?
|
||||
MusicBrainz::Tools::Cache.cache_contents(url) {
|
||||
get_contents url
|
||||
}
|
||||
end
|
||||
|
||||
def get_contents(url)
|
||||
response = nil
|
||||
|
||||
config.tries_limit.times {
|
||||
time_passed = Time.now.to_f - @@last_query_time
|
||||
sleep(config.query_interval - time_passed) if time_passed < config.query_interval
|
||||
|
||||
begin
|
||||
response = open(url, "User-Agent" => config.user_agent)
|
||||
@@last_query_time = Time.now.to_f
|
||||
rescue => e
|
||||
response = nil if e.io.status[0].to_i == 404
|
||||
end
|
||||
|
||||
break unless response.nil?
|
||||
}
|
||||
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
module MusicBrainz
|
||||
VERSION = "0.7.1"
|
||||
end
|
|
@ -1,6 +1,4 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
require File.expand_path('../lib/version', __FILE__)
|
||||
require File.expand_path('../lib/musicbrainz/version', __FILE__)
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.authors = ["Gregory Eremin"]
|
||||
|
@ -8,16 +6,16 @@ Gem::Specification.new do |gem|
|
|||
gem.summary = %q{MusicBrainz Web Service wrapper with ActiveRecord-style models}
|
||||
gem.homepage = "http://github.com/magnolia-fan/musicbrainz"
|
||||
|
||||
gem.files = `git ls-files`.split($\)
|
||||
gem.files = %x{ git ls-files }.split($\)
|
||||
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
||||
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
||||
gem.name = "musicbrainz"
|
||||
gem.require_paths = ["lib"]
|
||||
gem.require_paths = %w[ lib ]
|
||||
gem.version = MusicBrainz::VERSION
|
||||
gem.license = "MIT"
|
||||
|
||||
gem.add_dependency("faraday")
|
||||
gem.add_dependency("nokogiri")
|
||||
gem.add_development_dependency("rake")
|
||||
gem.add_development_dependency("awesome_print")
|
||||
gem.add_development_dependency("rspec")
|
||||
gem.add_development_dependency("awesome_print")
|
||||
end
|
||||
|
|
|
@ -4,35 +4,47 @@ require "spec_helper"
|
|||
|
||||
describe MusicBrainz do
|
||||
before(:all) {
|
||||
@old_cache_path = MusicBrainz::Tools::Cache.cache_path
|
||||
@old_cache_path = MusicBrainz.config.cache_path
|
||||
@old_query_interval = MusicBrainz.config.query_interval
|
||||
}
|
||||
|
||||
before(:each) {
|
||||
$stdout.stub!(:puts)
|
||||
MusicBrainz::Tools::Cache.cache_path = nil
|
||||
MusicBrainz.config.cache_path = nil
|
||||
MusicBrainz.config.query_interval = nil
|
||||
}
|
||||
|
||||
after(:all) {
|
||||
MusicBrainz::Tools::Cache.cache_path = @old_cache_path
|
||||
MusicBrainz.config.cache_path = @old_cache_path
|
||||
MusicBrainz.config.query_interval = @old_query_interval
|
||||
}
|
||||
|
||||
it "allows deprecated use of cache_path" do
|
||||
MusicBrainz::Tools::Cache.cache_path = "some/path"
|
||||
MusicBrainz::cache_path.should == "some/path"
|
||||
MusicBrainz.config.cache_path = "test1"
|
||||
|
||||
MusicBrainz::Tools::Cache.cache_path.should == "test1"
|
||||
MusicBrainz.cache_path.should == "test1"
|
||||
end
|
||||
|
||||
it "allows deprecated use of cache_path=" do
|
||||
MusicBrainz.cache_path = "some/path"
|
||||
MusicBrainz::Tools::Cache.cache_path.should == "some/path"
|
||||
MusicBrainz::Tools::Cache.cache_path = "test2"
|
||||
MusicBrainz.config.cache_path.should == "test2"
|
||||
|
||||
MusicBrainz.cache_path = "test3"
|
||||
MusicBrainz.config.cache_path.should == "test3"
|
||||
end
|
||||
|
||||
it "allows deprecated use of query_interval" do
|
||||
MusicBrainz::Tools::Proxy.query_interval = 2
|
||||
MusicBrainz::query_interval.should == 2
|
||||
MusicBrainz.config.query_interval = 2
|
||||
|
||||
MusicBrainz::Tools::Proxy.query_interval.should == 2
|
||||
MusicBrainz.query_interval.should == 2
|
||||
end
|
||||
|
||||
it "allows deprecated use of query_interval=" do
|
||||
MusicBrainz.query_interval = 2
|
||||
MusicBrainz::Tools::Proxy.query_interval.should == 2
|
||||
MusicBrainz::Tools::Proxy.query_interval = 3
|
||||
MusicBrainz.config.query_interval.should == 3
|
||||
|
||||
MusicBrainz.query_interval = 4
|
||||
MusicBrainz.config.query_interval.should == 4
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,15 +24,9 @@ describe MusicBrainz::Artist do
|
|||
matches = MusicBrainz::Artist.search('Chris Martin')
|
||||
|
||||
matches[0][:score].should == 100
|
||||
matches[0][:mbid].should == "98d1ec5a-dd97-4c0b-9c83-7928aac89bca"
|
||||
matches[0][:id].should == "98d1ec5a-dd97-4c0b-9c83-7928aac89bca"
|
||||
matches[1][:score].should == 100
|
||||
matches[1][:mbid].should == "af2ab893-3212-4226-9e73-73a1660b6952"
|
||||
matches[2][:score].should == 95
|
||||
matches[2][:mbid].should == "444d1b63-534b-4ea6-89f0-0af6ab2e20c3"
|
||||
matches[3][:score].should == 95
|
||||
matches[3][:mbid].should == "b732a912-af95-472c-be52-b14610734c64"
|
||||
matches[4][:score].should == 95
|
||||
matches[4][:mbid].should == "90fff570-a4ef-4cd4-ba21-e00c7261b05a"
|
||||
matches[1][:id].should == "af2ab893-3212-4226-9e73-73a1660b6952"
|
||||
end
|
||||
|
||||
it "finds name first than alias" do
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
require "ap"
|
||||
|
||||
require "musicbrainz"
|
||||
|
||||
MusicBrainz::Tools::Cache.cache_path = "tmp/cache"
|
||||
MusicBrainz.configure do |c|
|
||||
test_email = %x{ git config --global --get user.email }.gsub(/\n/, "")
|
||||
test_email = "magnolia_fan@me.com" if test_email.empty?
|
||||
|
||||
c.app_name = "MusicBrainzGemTestSuite"
|
||||
c.app_version = MusicBrainz::VERSION
|
||||
c.contact = test_email
|
||||
c.perform_caching = true
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
# Configuration is not currently necessary
|
||||
|
|
|
@ -1,59 +1,64 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
|
||||
require "ostruct"
|
||||
require "spec_helper"
|
||||
|
||||
describe MusicBrainz::Tools::Cache do
|
||||
before(:all) do
|
||||
@old_cache_path = MusicBrainz::Tools::Cache.cache_path
|
||||
@tmp_cache_path = File.join(File.dirname(__FILE__), '../../tmp/cache/tools')
|
||||
@tmp_cache_path = File.join(File.dirname(__FILE__), "../../tmp/cache/test")
|
||||
@test_mbid = "69b39eab-6577-46a4-a9f5-817839092033"
|
||||
@test_cache_file = "#{@tmp_cache_path}/03/48/ec6c2bee685d9a96f95ed46378f624714e7a4650b0d44c1a8eee5bac2480.xml"
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
MusicBrainz::Tools::Cache.cache_path = @old_cache_path
|
||||
MusicBrainz.config.cache_path = @old_cache_path
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
file_path = File.join(File.dirname(__FILE__), "../fixtures/kasabian.xml")
|
||||
@test_response = ::StringIO.new(File.open(file_path).gets)
|
||||
@test_response = File.open(file_path).read
|
||||
end
|
||||
|
||||
context "with cache enabled" do
|
||||
it "calls get contents only once when requesting the resource twice" do
|
||||
MusicBrainz::Tools::Cache.cache_path = @tmp_cache_path
|
||||
mbid = "69b39eab-6577-46a4-a9f5-817839092033"
|
||||
it "calls http only once when requesting the resource twice" do
|
||||
MusicBrainz.config.cache_path = @tmp_cache_path
|
||||
File.exist?(@test_cache_file).should be_false
|
||||
|
||||
MusicBrainz::Tools::Proxy.stub(:get_contents).and_return(@test_response)
|
||||
MusicBrainz::Tools::Proxy.should_receive(:get_contents).once
|
||||
# Stubbing
|
||||
MusicBrainz::Client.http.stub(:get).and_return(OpenStruct.new(status: 200, body: @test_response))
|
||||
MusicBrainz::Client.http.should_receive(:get).once
|
||||
|
||||
File.exist?("#{@tmp_cache_path}/artist/#{mbid}?inc=url-rels").should be_false
|
||||
artist = MusicBrainz::Artist.find(mbid)
|
||||
artist.should be_a_kind_of(MusicBrainz::Artist)
|
||||
2.times do
|
||||
artist = MusicBrainz::Artist.find(@test_mbid)
|
||||
artist.should be_a_kind_of(MusicBrainz::Artist)
|
||||
File.exist?(@test_cache_file).should be_true
|
||||
end
|
||||
|
||||
File.exist?("#{@tmp_cache_path}/artist/#{mbid}?inc=url-rels").should be_true
|
||||
artist = MusicBrainz::Artist.find(mbid)
|
||||
artist.should be_a_kind_of(MusicBrainz::Artist)
|
||||
|
||||
MusicBrainz::Tools::Cache.clear_cache
|
||||
MusicBrainz::Client.clear_cache
|
||||
end
|
||||
end
|
||||
|
||||
context "with cache disabled" do
|
||||
it "calls get contents twice when requesting the resource twice" do
|
||||
MusicBrainz::Tools::Cache.cache_path = nil
|
||||
mbid = "69b39eab-6577-46a4-a9f5-817839092033"
|
||||
it "calls http twice when requesting the resource twice" do
|
||||
MusicBrainz.config.perform_caching = false
|
||||
File.exist?(@test_cache_file).should be_false
|
||||
|
||||
MusicBrainz::Tools::Proxy.stub(:get_contents).and_return(@test_response)
|
||||
MusicBrainz::Tools::Proxy.should_receive(:get_contents).twice
|
||||
# Hacking for test performance purposes
|
||||
MusicBrainz.config.query_interval = 0.0
|
||||
|
||||
File.exist?("#{@tmp_cache_path}/artist/#{mbid}?inc=url-rels").should be_false
|
||||
artist = MusicBrainz::Artist.find(mbid)
|
||||
artist.should be_a_kind_of(MusicBrainz::Artist)
|
||||
# Stubbing
|
||||
MusicBrainz::Client.http.stub(:get).and_return(OpenStruct.new(status: 200, body: @test_response))
|
||||
MusicBrainz::Client.http.should_receive(:get).twice
|
||||
|
||||
File.exist?("#{@tmp_cache_path}/artist/#{mbid}?inc=url-rels").should be_false
|
||||
@test_response.rewind
|
||||
MusicBrainz.stub(:get_contents).and_return(@test_response)
|
||||
artist = MusicBrainz::Artist.find(mbid)
|
||||
artist.should be_a_kind_of(MusicBrainz::Artist)
|
||||
2.times do
|
||||
artist = MusicBrainz::Artist.find(@test_mbid)
|
||||
artist.should be_a_kind_of(MusicBrainz::Artist)
|
||||
File.exist?(@test_cache_file).should be_false
|
||||
end
|
||||
|
||||
MusicBrainz.config.perform_caching = true
|
||||
MusicBrainz.config.query_interval = 1.5
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue