1
0
Fork 0

Merge branch 'track_search' of https://github.com/tomwolfe/musicbrainz into tomwolfe-track_search

This commit is contained in:
Mathias Gawlista 2013-05-06 19:58:58 +02:00
commit 6d0d80d9db
13 changed files with 94 additions and 24 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ coverage
tmp tmp
Gemfile.lock Gemfile.lock
.gem .gem
*.swp

View File

@ -4,3 +4,4 @@ Applicat (https://github.com/Applicat)
Jens Fahnenbruck (https://github.com/jigfox) Jens Fahnenbruck (https://github.com/jigfox)
Sander Nieuwenhuizen (https://github.com/munkius) Sander Nieuwenhuizen (https://github.com/munkius)
Savater Sebastien (https://github.com/blakink) Savater Sebastien (https://github.com/blakink)
Thomas Wolfe (https://github.com/tomwolfe)

View File

@ -1,2 +1,2 @@
source :rubygems source 'https://rubygems.org'
gemspec gemspec

View File

@ -80,9 +80,9 @@ MusicBrainz::ReleaseGroup
```ruby ```ruby
# Class Methods # Class Methods
MusicBrainz::ReleaseGroup.find(id) MusicBrainz::ReleaseGroup.find(id)
MusicBrainz::ReleaseGroup.find_by_artist_and_title(artist_name, title, type: 'Album') MusicBrainz::ReleaseGroup.find_by_artist_and_title(artist_name, title, 'Album') # 3rd arg optional
MusicBrainz::ReleaseGroup.search(artist_name, title) MusicBrainz::ReleaseGroup.search(artist_name, title)
MusicBrainz::ReleaseGroup.search(artist_name, title, type: 'Album') MusicBrainz::ReleaseGroup.search(artist_name, title, 'Album') # 3rd arg optional
# Instance Methods # Instance Methods
@release_group.releases @release_group.releases
@ -125,6 +125,7 @@ MusicBrainz::Track
```ruby ```ruby
# Class Methods # Class Methods
MusicBrainz::Track.find(id) MusicBrainz::Track.find(id)
MusicBrainz::ReleaseGroup.search(artist_name, track_name)
# Fields # Fields
{ {

View File

@ -29,6 +29,7 @@ require "musicbrainz/bindings/release_group_releases"
require "musicbrainz/bindings/release" require "musicbrainz/bindings/release"
require "musicbrainz/bindings/release_tracks" require "musicbrainz/bindings/release_tracks"
require "musicbrainz/bindings/track" require "musicbrainz/bindings/track"
require "musicbrainz/bindings/track_search"
module MusicBrainz module MusicBrainz
GH_PAGE_URL = "http://git.io/brainz" GH_PAGE_URL = "http://git.io/brainz"

View File

@ -0,0 +1,21 @@
# encoding: UTF-8
module MusicBrainz
module Bindings
module TrackSearch
def parse(xml)
xml.xpath('./recording-list/recording').map do |xml|
{
id: (xml.attribute('id').value rescue nil),
mbid: (xml.attribute('id').value rescue nil), # Old shit
title: (xml.xpath('./title').text.gsub(/[`]/, "'") rescue nil),
artist: (xml.xpath('./artist-credit/name-credit/artist/name').text rescue nil),
releases: (xml.xpath('./release-list/release/title').map{ |xml| xml.text } rescue []),
score: (xml.attribute('score').value.to_i rescue nil)
} rescue nil
end.delete_if{ |item| item.nil? }
end
extend self
end
end
end

View File

@ -25,11 +25,7 @@ module MusicBrainz
end end
def search(name) def search(name)
name = CGI.escape(name).gsub(/\!/, '\!') super({artist: name})
client.load(:artist, { query: "artist:#{name}", limit: 10 }, {
binding: :artist_search
})
end end
def discography(mbid) def discography(mbid)

View File

@ -23,6 +23,38 @@ module MusicBrainz
def client def client
MusicBrainz.client MusicBrainz.client
end end
def search(hash)
hash = escape_strings(hash)
query_val = build_query(hash)
underscore_name = self.name[13..-1].underscore
client.load(underscore_name.to_sym, { query: query_val, limit: 10 }, { binding: underscore_name.insert(-1,"_search").to_sym })
end
class ::String
def underscore
self.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
end
def build_query(hash)
return ["#{hash.first[0].to_s}:\"#{hash.first[1]}\""] if hash.size ==1
arr ||= []
hash.each { |k, v| arr << "#{k.to_s}:\"#{hash[k]}\"" }
arr.join(' AND ')
end
def escape_strings(hash)
hash.each { |k, v| hash[k] = CGI.escape(v).gsub(/\!/, '\!') }
hash
end
# these probably should be private... but I'm not sure how to get it to work in a module...
# private_class_method :build_query, :escape_strings
end end
module InstanceMethods module InstanceMethods

View File

@ -25,20 +25,16 @@ module MusicBrainz
}) })
end end
def search(artist_name, title, options = {}) def search(artist_name, title, type = nil)
artist_name = CGI.escape(artist_name).gsub(/\!/, '\!') if type
title = CGI.escape(title).gsub(/\!/, '\!') super({artist: artist_name, releasegroup: title, type: type})
query = ["artist:\"#{artist_name}\"", "releasegroup:\"#{title}\""] else
query << "type: #{options[:type]}" if options[:type] super({artist: artist_name, releasegroup: title})
end
client.load(
:release_group, { query: query.join(' AND '), limit: 10 },
{ binding: :release_group_search }
)
end end
def find_by_artist_and_title(artist_name, title, options = {}) def find_by_artist_and_title(artist_name, title, type = nil )
matches = search(artist_name, title, options) matches = search(artist_name, title, type)
matches.empty? ? nil : find(matches.first[:id]) matches.empty? ? nil : find(matches.first[:id])
end end
end end

View File

@ -12,6 +12,10 @@ module MusicBrainz
create_model: :track create_model: :track
}) })
end end
def search(artist_name, track_name)
super({artist: artist_name, recording: track_name})
end
end end
end end
end end

View File

@ -5,8 +5,8 @@ require "spec_helper"
describe MusicBrainz::Bindings::ReleaseGroupSearch do describe MusicBrainz::Bindings::ReleaseGroupSearch do
describe '.parse' do describe '.parse' do
it "gets correct release group data" do it "gets correct release group data" do
response = '<release-group-list><release-group id="246bc928-2dc8-35ba-80ee-7a0079de1632" type="Single" ext:score="100"><title>Empire</title></release-group>' response = '<metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0"><release-group-list><release-group id="246bc928-2dc8-35ba-80ee-7a0079de1632" type="Single" ext:score="100"><title>Empire</title></release-group></release-group-list></metadata>'
described_class.parse(Nokogiri::XML.parse(response)).should == [ described_class.parse(Nokogiri::XML.parse(response).remove_namespaces!.xpath('/metadata')).should == [
{ {
id: '246bc928-2dc8-35ba-80ee-7a0079de1632', mbid: '246bc928-2dc8-35ba-80ee-7a0079de1632', id: '246bc928-2dc8-35ba-80ee-7a0079de1632', mbid: '246bc928-2dc8-35ba-80ee-7a0079de1632',
title: 'Empire', type: 'Single', score: 100 title: 'Empire', type: 'Single', score: 100
@ -14,4 +14,4 @@ describe MusicBrainz::Bindings::ReleaseGroupSearch do
] ]
end end
end end
end end

View File

@ -0,0 +1,17 @@
# -*- encoding: utf-8 -*-
require "spec_helper"
describe MusicBrainz::Bindings::TrackSearch do
describe '.parse' do
it "gets correct Track (really recording) data" do
response = '<metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0"><recording-list offset="0" count="1"><recording id="0b382a13-32f0-4743-9248-ba5536a6115e" ext:score="100"><title>King Fred</title><artist-credit><name-credit><artist id="f52f7a92-d495-4d32-89e7-8b1e5b8541c8"><name>Too Much Joy</name></artist></name-credit></artist-credit><release-list><release id="8442e42b-c40a-4817-89a0-dbe663c94d2d"><title>Green Eggs and Crack</title></release></release-list></recording></recording-list></metadata>'
described_class.parse(Nokogiri::XML.parse(response).remove_namespaces!.xpath('/metadata')).should == [
{
id: '0b382a13-32f0-4743-9248-ba5536a6115e', mbid: '0b382a13-32f0-4743-9248-ba5536a6115e',
title: 'King Fred', artist: 'Too Much Joy', releases: ['Green Eggs and Crack'], score: 100
}
]
end
end
end

View File

@ -41,7 +41,7 @@ describe MusicBrainz::ReleaseGroup do
context 'with type filter' do context 'with type filter' do
it "searches release group by artist name and title" do it "searches release group by artist name and title" do
matches = MusicBrainz::ReleaseGroup.search('Kasabian', 'Empire', type: 'Album') matches = MusicBrainz::ReleaseGroup.search('Kasabian', 'Empire', 'Album')
matches.length.should be > 0 matches.length.should be > 0
matches.first[:title].should == 'Empire' matches.first[:title].should == 'Empire'
matches.first[:type].should == 'Album' matches.first[:type].should == 'Album'