buntine-discogs 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|