buntine-discogs 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +61 -0
- data/Rakefile +27 -0
- data/discogs.gemspec +19 -0
- data/lib/discogs.rb +10 -0
- data/lib/wrapper/resource.rb +75 -0
- data/lib/wrapper/resource_mappings.rb +80 -0
- data/lib/wrapper/resources/artist.rb +16 -0
- data/lib/wrapper/resources/artist_release.rb +16 -0
- data/lib/wrapper/resources/format.rb +11 -0
- data/lib/wrapper/resources/generic_list.rb +29 -0
- data/lib/wrapper/resources/image.rb +11 -0
- data/lib/wrapper/resources/label.rb +16 -0
- data/lib/wrapper/resources/label_release.rb +17 -0
- data/lib/wrapper/resources/release.rb +22 -0
- data/lib/wrapper/resources/release_artist.rb +18 -0
- data/lib/wrapper/resources/release_label.rb +10 -0
- data/lib/wrapper/resources/search.rb +17 -0
- data/lib/wrapper/resources/search_result.rb +16 -0
- data/lib/wrapper/resources/track.rb +15 -0
- data/lib/wrapper/wrapper.rb +88 -0
- data/spec/resource_spec.rb +27 -0
- data/spec/resources/artist_release_spec.rb +55 -0
- data/spec/resources/artist_spec.rb +15 -0
- data/spec/resources/format_spec.rb +41 -0
- data/spec/resources/generic_list_spec.rb +66 -0
- data/spec/resources/image_spec.rb +43 -0
- data/spec/resources/label_release_spec.rb +55 -0
- data/spec/resources/label_spec.rb +15 -0
- data/spec/resources/release_artist_spec.rb +43 -0
- data/spec/resources/release_label_spec.rb +31 -0
- data/spec/resources/release_spec.rb +15 -0
- data/spec/resources/search_result_spec.rb +47 -0
- data/spec/resources/search_spec.rb +15 -0
- data/spec/resources/track_spec.rb +56 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/wrapper_methods/get_artist_spec.rb +95 -0
- data/spec/wrapper_methods/get_label_spec.rb +91 -0
- data/spec/wrapper_methods/get_release_spec.rb +125 -0
- data/spec/wrapper_methods/search_spec.rb +99 -0
- data/spec/wrapper_spec.rb +100 -0
- metadata +93 -0
data/README
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
Discogs::Wrapper
|
2
|
+
--------------------------
|
3
|
+
|
4
|
+
ABOUT
|
5
|
+
|
6
|
+
A 100% Ruby wrapper of the http://www.discogs.com API. No dependencies, no extra gems. :)
|
7
|
+
|
8
|
+
Discogs::Wrapper abstracts all the nasty boilerplate code needed to interact with the Discogs API. It gives you direct access to the information you need.
|
9
|
+
|
10
|
+
Full support for everything in version 1.0 of the API:
|
11
|
+
|
12
|
+
- Artists
|
13
|
+
- Releases
|
14
|
+
- Labels
|
15
|
+
- Searching
|
16
|
+
|
17
|
+
The API is documented here: http://www.discogs.com/help/api
|
18
|
+
|
19
|
+
INSTALLATION
|
20
|
+
|
21
|
+
You can install the library via Rubygems:
|
22
|
+
|
23
|
+
$ gem sources -a http://gems.github.com
|
24
|
+
$ sudo gem install buntine-discogs
|
25
|
+
|
26
|
+
|
27
|
+
USAGE
|
28
|
+
|
29
|
+
To use this library, you must supply a valid Discogs API key.
|
30
|
+
|
31
|
+
wrapper = Discogs::Wrapper.new("my_api_key")
|
32
|
+
|
33
|
+
|
34
|
+
Accessing information is easy:
|
35
|
+
|
36
|
+
artist = wrapper.get_artist("Master's Hammer")
|
37
|
+
release = wrapper.get_release("611973") # Supply an ID.
|
38
|
+
label = wrapper.get_label("Monitor Records")
|
39
|
+
search_results = wrapper.search("Necrovore")
|
40
|
+
|
41
|
+
artist.name # => Master's Hammer
|
42
|
+
artist.releases[0].title # => Finished
|
43
|
+
artist.releases[1].year # => 1989
|
44
|
+
artist.releases[4].extraartists # => [ "Arakain", "Debustrol" ]
|
45
|
+
|
46
|
+
release.title # => "Ritual"
|
47
|
+
release.labels[0].name # => "Osmose Productions"
|
48
|
+
release.formats[0].descriptions[0] # => "LP"
|
49
|
+
release.styles # => [ "Black Metal", "Death Metal" ]
|
50
|
+
release.tracklist[1].title # => "Pad modly"
|
51
|
+
|
52
|
+
label.images[0].width # => "220"
|
53
|
+
label.releases.length # => 22
|
54
|
+
label.releases[3].artist # => "Root"
|
55
|
+
label.releases[7].catno # => "MON007"
|
56
|
+
|
57
|
+
search.total_results # => "124"
|
58
|
+
search.exactresults[0].type # => "artist"
|
59
|
+
search.exactresults[0].title # => "Necrovore"
|
60
|
+
search.searchresults[3].title # => "Necrovore - Demo '87"
|
61
|
+
search.searchresults[3].summary # => "First and only demo tape"
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
desc "Run all specs in spec directory"
|
9
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
10
|
+
t.spec_opts = ["--colour", "--format progress", "--loadby mtime", "--reverse"]
|
11
|
+
t.spec_files = FileList[ 'spec/**/*_spec.rb' ]
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Run all specs and generate RCov report"
|
15
|
+
Spec::Rake::SpecTask.new('cov') do |t|
|
16
|
+
t.spec_files = FileList['spec/**/*.rb']
|
17
|
+
t.spec_opts = ["--colour"]
|
18
|
+
t.rcov = true
|
19
|
+
t.rcov_opts = ['-T --no-html --exclude', 'spec\/,gems\/']
|
20
|
+
end
|
21
|
+
|
22
|
+
spec = eval(File.read("discogs.gemspec"))
|
23
|
+
|
24
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
25
|
+
# pkg.need_zip = true
|
26
|
+
# pkg.need_tar = true
|
27
|
+
end
|
data/discogs.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
|
3
|
+
s.name = "discogs"
|
4
|
+
s.version = "0.3.1"
|
5
|
+
s.date = "2009-07-04"
|
6
|
+
s.summary = "Discogs::Wrapper is a full wrapper for the http://www.discogs.com API"
|
7
|
+
s.homepage = "http://www.github.com/buntine/discogs"
|
8
|
+
s.email = "info@andrewbuntine.com"
|
9
|
+
s.authors = ["Andrew Buntine"]
|
10
|
+
|
11
|
+
s.description = "Discogs::Wrapper is a full wrapper for the http://www.discogs.com API"
|
12
|
+
|
13
|
+
s.files = ["lib/wrapper", "lib/wrapper/resource_mappings.rb", "lib/wrapper/wrapper.rb", "lib/wrapper/resource.rb", "lib/wrapper/resources", "lib/wrapper/resources/format.rb", "lib/wrapper/resources/search.rb", "lib/wrapper/resources/label_release.rb", "lib/wrapper/resources/artist.rb", "lib/wrapper/resources/release_artist.rb", "lib/wrapper/resources/artist_release.rb", "lib/wrapper/resources/release_label.rb", "lib/wrapper/resources/generic_list.rb", "lib/wrapper/resources/search_result.rb", "lib/wrapper/resources/label.rb", "lib/wrapper/resources/image.rb", "lib/wrapper/resources/track.rb", "lib/wrapper/resources/release.rb", "lib/discogs.rb", "Rakefile", "README", "discogs.gemspec"]
|
14
|
+
|
15
|
+
s.test_files = ["spec/wrapper_methods/get_release_spec.rb", "spec/wrapper_methods/search_spec.rb", "spec/wrapper_methods/get_artist_spec.rb", "spec/wrapper_methods/get_label_spec.rb", "spec/resource_spec.rb", "spec/resources/label_spec.rb", "spec/resources/generic_list_spec.rb", "spec/resources/artist_release_spec.rb", "spec/resources/artist_spec.rb", "spec/resources/release_artist_spec.rb", "spec/resources/search_spec.rb", "spec/resources/label_release_spec.rb", "spec/resources/release_label_spec.rb", "spec/resources/release_spec.rb", "spec/resources/search_result_spec.rb", "spec/resources/image_spec.rb", "spec/resources/track_spec.rb", "spec/resources/format_spec.rb", "spec/wrapper_spec.rb", "spec/spec_helper.rb"]
|
16
|
+
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
|
19
|
+
end
|
data/lib/discogs.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Represents a generic resource in the Discogs API.
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + "/resource_mappings"
|
4
|
+
|
5
|
+
class Discogs::Resource
|
6
|
+
|
7
|
+
include Discogs::ResourceMappings
|
8
|
+
|
9
|
+
def initialize(content)
|
10
|
+
@content = content
|
11
|
+
end
|
12
|
+
|
13
|
+
def original_content
|
14
|
+
@content
|
15
|
+
end
|
16
|
+
|
17
|
+
# Builds the resource with it's content.
|
18
|
+
def build!(remove_resp=true)
|
19
|
+
document = REXML::Document.new(@content, :ignore_whitespace_nodes => :all)
|
20
|
+
root_node = document.root
|
21
|
+
|
22
|
+
# Ignore the <resp> element if necessary.
|
23
|
+
if remove_resp and document.root.expanded_name == "resp"
|
24
|
+
root_node = root_node[0]
|
25
|
+
end
|
26
|
+
|
27
|
+
set_accessors_from_attributes(root_node)
|
28
|
+
|
29
|
+
# Traverse node children.
|
30
|
+
root_node.each_element do |element|
|
31
|
+
name = element.expanded_name.to_sym
|
32
|
+
setter = (name.to_s + "=").to_sym
|
33
|
+
|
34
|
+
singular = find_resource_for_name(name, :singular)
|
35
|
+
plural = singular ? nil : find_resource_for_name(name, :plural)
|
36
|
+
|
37
|
+
if !singular.nil?
|
38
|
+
nested_object = singular.send(:new, element.to_s)
|
39
|
+
self.send(setter, nested_object.build!)
|
40
|
+
elsif !plural.nil?
|
41
|
+
set_accessors_from_attributes(element)
|
42
|
+
|
43
|
+
self.send(setter, [])
|
44
|
+
element.each_element do |sub_element|
|
45
|
+
nested_object = plural.send(:new, sub_element.to_s)
|
46
|
+
self.send(name) << nested_object.build!
|
47
|
+
end
|
48
|
+
elsif self.respond_to? setter
|
49
|
+
self.send(setter, element.text)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_with_resp!
|
57
|
+
build!(false)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Sets accessors on _self_ from the attributes of the given element.
|
63
|
+
def set_accessors_from_attributes(element)
|
64
|
+
element.attributes.each_attribute do |attribute|
|
65
|
+
setter = (attribute.expanded_name + "=").to_sym
|
66
|
+
|
67
|
+
if self.respond_to? setter
|
68
|
+
self.send(setter, attribute.value)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
Dir[File.join(File.dirname(__FILE__), "resources", "*.rb")].each { |file| require file }
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Abstracts the resource-mapping class methods.
|
2
|
+
|
3
|
+
module Discogs::ResourceMappings
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
# Helper method to map resource to element in API response.
|
12
|
+
def map_to(*elements)
|
13
|
+
self.class_eval <<-EOF
|
14
|
+
def self.element_names
|
15
|
+
#{elements.inspect}
|
16
|
+
end
|
17
|
+
EOF
|
18
|
+
end
|
19
|
+
|
20
|
+
# Helper method to map pluralised resource to element in API response.
|
21
|
+
def map_to_plural(*elements)
|
22
|
+
self.class_eval <<-EOF
|
23
|
+
def self.plural_element_names
|
24
|
+
#{elements.inspect}
|
25
|
+
end
|
26
|
+
EOF
|
27
|
+
end
|
28
|
+
|
29
|
+
# Used by root classes (Discogs::Artist, etc) that should be built internally.
|
30
|
+
def no_mapping
|
31
|
+
self.class_eval <<-EOF
|
32
|
+
def self.element_names; []; end
|
33
|
+
def self.plural_element_names; []; end
|
34
|
+
EOF
|
35
|
+
end
|
36
|
+
|
37
|
+
# Element defaults to prevent excess boilerplate code.
|
38
|
+
def element_names
|
39
|
+
[ self.to_s.split("::")[-1].downcase.to_sym ]
|
40
|
+
end
|
41
|
+
def plural_element_names
|
42
|
+
[ (self.element_names[0].to_s + "s").to_sym ]
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def find_resource_for_name(name, type=:singular)
|
50
|
+
method = if type == :singular
|
51
|
+
:element_names
|
52
|
+
else
|
53
|
+
:plural_element_names
|
54
|
+
end
|
55
|
+
|
56
|
+
find_resource do |klass|
|
57
|
+
klass.constants.find do |const|
|
58
|
+
if klass.const_get(const).respond_to? method
|
59
|
+
klass.const_get(const).send(method).any? { |element| element.eql?(name) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Look in _namespace_ for a matching resource class.
|
66
|
+
# First looks in the children of _self_ namespace, and then looks more
|
67
|
+
# generally. Returns nil if nothing is found.
|
68
|
+
def find_resource(namespace=self.class, &matcher)
|
69
|
+
match = matcher.call(namespace)
|
70
|
+
|
71
|
+
if match
|
72
|
+
match = namespace.const_get(match)
|
73
|
+
elsif namespace == self.class
|
74
|
+
match = find_resource(Discogs, &matcher)
|
75
|
+
end
|
76
|
+
|
77
|
+
return match
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Represents an artist's release in the Discogs API.
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + "/artist"
|
4
|
+
|
5
|
+
class Discogs::Artist::Release < Discogs::Resource
|
6
|
+
|
7
|
+
attr_accessor :id,
|
8
|
+
:status,
|
9
|
+
:type,
|
10
|
+
:title,
|
11
|
+
:format,
|
12
|
+
:year,
|
13
|
+
:label,
|
14
|
+
:trackinfo
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Represents a generic list of items in the Discogs API.
|
2
|
+
|
3
|
+
class Discogs::GenericList < Discogs::Resource
|
4
|
+
|
5
|
+
map_to :descriptions, :genres, :aliases, :namevariations, :styles, :urls, :members, :sublabels
|
6
|
+
|
7
|
+
map_to_plural :lists
|
8
|
+
|
9
|
+
# Overload build method to provide custom process for
|
10
|
+
# converting contents into something useful.
|
11
|
+
def build!
|
12
|
+
@items = []
|
13
|
+
document = REXML::Document.new(@content)
|
14
|
+
|
15
|
+
document.root.each_element do |element|
|
16
|
+
@items << element.text
|
17
|
+
end
|
18
|
+
|
19
|
+
@items
|
20
|
+
end
|
21
|
+
|
22
|
+
# Provides post-build access to the list.
|
23
|
+
def [](index)
|
24
|
+
if @items.is_a?(Array)
|
25
|
+
@items[index]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Represents a labels release in the Discogs API.
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + "/label"
|
4
|
+
|
5
|
+
class Discogs::Label::Release < Discogs::Resource
|
6
|
+
|
7
|
+
attr_accessor :id,
|
8
|
+
:status,
|
9
|
+
:type,
|
10
|
+
:catno,
|
11
|
+
:artist,
|
12
|
+
:title,
|
13
|
+
:format,
|
14
|
+
:year,
|
15
|
+
:trackinfo
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Represents a release in the Discogs API.
|
2
|
+
|
3
|
+
class Discogs::Release < Discogs::Resource
|
4
|
+
|
5
|
+
no_mapping
|
6
|
+
|
7
|
+
attr_accessor :id,
|
8
|
+
:status,
|
9
|
+
:title,
|
10
|
+
:country,
|
11
|
+
:released,
|
12
|
+
:notes,
|
13
|
+
:images,
|
14
|
+
:artists,
|
15
|
+
:extraartists,
|
16
|
+
:labels,
|
17
|
+
:formats,
|
18
|
+
:styles,
|
19
|
+
:genres,
|
20
|
+
:tracklist
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Represents an release's artist in the Discogs API.
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + "/track"
|
4
|
+
|
5
|
+
class Discogs::Release::Artist < Discogs::Resource
|
6
|
+
|
7
|
+
map_to_plural :artists, :extraartists
|
8
|
+
|
9
|
+
attr_accessor :name,
|
10
|
+
:role,
|
11
|
+
:join,
|
12
|
+
:anv,
|
13
|
+
:tracks
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
# Define other classes that also replicate this structure.
|
18
|
+
class Discogs::Release::Track::Artist < Discogs::Release::Artist; end
|