bandcamp_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bandcamp.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Mike Williamson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # Bandcamp
2
+
3
+ This is a gem that wraps the Bandcamp API in a warm Rubyish hug.
4
+ To use it you will need to request an API key from them. For details see
5
+ [http://bandcamp.com/developer#key_request][].
6
+
7
+ # Usage
8
+
9
+ In your Gemfile
10
+ ```ruby
11
+ gem 'bandcamp', github: "sleepycat/bandcamp"
12
+ ```
13
+
14
+ ## Getting started:
15
+ ```ruby
16
+ require 'bandcamp'
17
+ Bandcamp.config.api_key = "your_api_key"
18
+ ```
19
+
20
+ ## Search
21
+
22
+ Search the Bandcamp.com API by band name:
23
+ ```ruby
24
+ matching_bands = Bandcamp.search "pitch black"
25
+ => [#<Bandcamp::Band:0x00000001efa168>, #<Bandcamp::Band:0x00000001e53278>, ...]
26
+ ```
27
+
28
+ ## Resolving URLs
29
+
30
+ Bandcamp lets you resolve a given url to given band, track or album:
31
+
32
+ ```ruby
33
+ sea_oleena = Bandcamp.resolve.url "seaoleena.bandcamp.com"
34
+ => #<Bandcamp::Band:0x00000001ef20f8>
35
+
36
+ emoxygen_by_sun_monx = Bandcamp.resolve.url "http://interchill.bandcamp.com/track/emoxygen"
37
+ ```
38
+
39
+ ## Getting stuff
40
+
41
+ A specific track:
42
+ ```ruby
43
+ evolution_11 = Bandcamp.get.track 1735088360
44
+ => #<Bandcamp::Track:0x0000000162c7e8>
45
+ ```
46
+
47
+ Many specific tracks:
48
+ ```ruby
49
+ tracks = Bandcamp.get.tracks 1735088360, 1739611553
50
+ => [#<Bandcamp::Track:0x00000001316ab8>, #<Bandcamp::Track:0x00000001314a10>, ...]
51
+ ```
52
+
53
+ A band:
54
+ ```ruby
55
+ pitchblack = Bandcamp.get.band 950934886
56
+ => #<Bandcamp::Band:0x000000017d43e8>
57
+ ```
58
+
59
+ An album:
60
+ ```ruby
61
+ ape_to_angel = Bandcamp.get.album 2909726980
62
+ => #<Bandcamp::Album:0x00000001e20c60>
63
+ ```
64
+
65
+ ## TODO list
66
+
67
+ * Making the objects a little smarter. Tracks should be able to tell you what album
68
+ they are from and what band did them. Same sort of thing for the other
69
+ objects.
70
+ * Rails 3 integration so you can use these ojects with partials and form_for.
71
+ * Duck typing helpers along the lines of [ActiveSupport's
72
+ #acts_like?](http://apidock.com/rails/Object/acts_like%3F)
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create new Pull Request
81
+
82
+ ### License
83
+
84
+ (The MIT License)
85
+
86
+ Copyright (c) 2013 Mike Williamson
87
+
88
+ Permission is hereby granted, free of charge, to any person obtaining
89
+ a copy of this software and associated documentation files (the
90
+ "Software"), to deal in the Software without restriction, including
91
+ without limitation the rights to use, copy, modify, merge, publish,
92
+ distribute, sublicense, and/or sell copies of the Software, and to
93
+ permit persons to whom the Software is furnished to do so, subject to
94
+ the following conditions:
95
+
96
+ The above copyright notice and this permission notice shall be
97
+ included in all copies or substantial portions of the Software.
98
+
99
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
100
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
101
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
102
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
103
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
104
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
105
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
106
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bandcamp/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "bandcamp_api"
8
+ gem.version = Bandcamp::VERSION
9
+ gem.authors = ["Mike Williamson"]
10
+ gem.email = ["blessedbyvirtuosity@gmail.com"]
11
+ gem.description = "A helper library for accessing the Bandcamp.com api"
12
+ gem.summary = "A library for communicating with the Bandcamp.com api and wrapping the various types of data to make it easier to work with."
13
+ #gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_development_dependency("rspec")
20
+ gem.add_runtime_dependency("multi_json")
21
+ end
@@ -0,0 +1,14 @@
1
+ require 'bandcamp/methodical'
2
+
3
+ module Bandcamp
4
+ class Album
5
+
6
+ include Methodical
7
+
8
+ def initialize album_hash
9
+ to_methods album_hash
10
+ end
11
+
12
+
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ require 'bandcamp/methodical'
2
+
3
+ module Bandcamp
4
+ class Band
5
+ include Methodical
6
+
7
+ def initialize attrs_hash
8
+ to_methods attrs_hash
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module Bandcamp
2
+ class ConfigurationError < StandardError; end
3
+
4
+ class Configuration
5
+
6
+ attr_writer :api_key
7
+
8
+ def api_key
9
+ raise ConfigurationError, "You need to set an API key" unless @api_key
10
+ @api_key
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,61 @@
1
+ require 'bandcamp/band'
2
+ require 'bandcamp/album'
3
+ require 'bandcamp/track'
4
+ require 'bandcamp/request'
5
+
6
+ module Bandcamp
7
+ class Getter
8
+
9
+ def initialize request
10
+ @request = request
11
+ end
12
+
13
+ def track track_id
14
+ response = @request.track track_id
15
+ response.nil? ? nil : Track.new(response)
16
+ end
17
+
18
+ def tracks *tracks
19
+ track_list = tracks.join(',')
20
+ response = @request.track track_list
21
+ if response.nil?
22
+ []
23
+ else
24
+ response.collect{|key,val| Track.new val}
25
+ end
26
+ end
27
+
28
+ def album album_id
29
+ response = @request.album album_id
30
+ response.nil? ? nil : Album.new(response)
31
+ end
32
+
33
+ def search band_name
34
+ response = @request.search band_name
35
+ if response.nil?
36
+ []
37
+ else
38
+ response.collect{|band_json| Band.new band_json}
39
+ end
40
+ end
41
+
42
+ def band name
43
+ response = @request.band name
44
+ response.nil? ? nil : Band.new(response)
45
+ end
46
+
47
+ def url address
48
+ response = @request.url address
49
+ return nil if response.nil?
50
+ case
51
+ when response.has_key?("album_id")
52
+ album(response["album_id"])
53
+ when response.has_key?("track_id")
54
+ track(response["track_id"])
55
+ when (response.keys.length == 1) && response.has_key?("band_id")
56
+ band(response["band_id"])
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,15 @@
1
+ module Bandcamp
2
+ module Methodical
3
+
4
+ def to_methods hash
5
+ eigenclass = class << self; self; end
6
+ hash.each_pair do |key, val|
7
+ eigenclass.instance_eval { attr_reader key.to_sym }
8
+ instance_variable_set("@#{key}".to_sym, val)
9
+ end
10
+ end
11
+
12
+ private :to_methods
13
+
14
+ end
15
+ end
@@ -0,0 +1,125 @@
1
+ require 'bandcamp'
2
+ require 'net/http'
3
+ require 'multi_json'
4
+
5
+ module Bandcamp
6
+
7
+ # A helper class for assembling a uri to query the API
8
+
9
+ class Request
10
+
11
+ attr_reader :api_key
12
+
13
+ def initialize api_key
14
+ @uri = URI('http://api.bandcamp.com')
15
+ @api_key = api_key
16
+ end
17
+
18
+ def host
19
+ @uri.host
20
+ end
21
+
22
+ def path
23
+ @uri.path
24
+ end
25
+
26
+ def path= path
27
+ @uri.path = path
28
+ end
29
+
30
+ def track trackid
31
+ self.type :track
32
+ self.query = { track_id: trackid }
33
+ response = dispatch
34
+ response.empty? ? nil : response
35
+ end
36
+
37
+ def album albumid
38
+ type :album
39
+ self.query={ album_id: albumid }
40
+ response = dispatch
41
+ response.empty? ? nil : response
42
+ end
43
+
44
+ def band bandid
45
+ type :band
46
+ self.query={ band_id: bandid }
47
+ response = dispatch
48
+ response["error"] ? nil : response
49
+ end
50
+
51
+ def url bandcamp_url
52
+ type :url
53
+ self.query = {url: bandcamp_url}
54
+ response = dispatch
55
+ response["error"] ? nil : response
56
+ end
57
+
58
+ def discography bandid
59
+ type :discography
60
+ self.query = {band_id: bandid}
61
+ response = dispatch
62
+ response["discography"].empty? ? nil : response["discography"]
63
+ end
64
+
65
+ def search name
66
+ type :search
67
+ self.query = {name: name}
68
+ response = dispatch
69
+ response["results"].empty? ? nil : response["results"]
70
+ end
71
+
72
+ def type req_type
73
+ self.path = case req_type
74
+ when :track
75
+ '/api/track/3/info'
76
+ when :album
77
+ '/api/album/2/info'
78
+ when :discography
79
+ '/api/band/3/discography'
80
+ when :search
81
+ '/api/band/3/search'
82
+ when :band
83
+ '/api/band/3/info'
84
+ when :url
85
+ '/api/url/1/info'
86
+ else
87
+ raise UnknownTypeError, "The Bandcamp API does not support this type of request."
88
+ end
89
+ end
90
+
91
+ def uri
92
+ @uri.to_s
93
+ end
94
+
95
+ def query= params
96
+ @uri.query = generate_params(params)
97
+ end
98
+
99
+ def query
100
+ @uri.query
101
+ end
102
+
103
+ def generate_params params
104
+ add_key_param(params).map{|key,val| "#{URI.encode(key.to_s)}=#{URI.encode(val.to_s)}"}.join('&')
105
+ end
106
+
107
+ def add_key_param params
108
+ {key: @api_key}.merge params
109
+ end
110
+
111
+ def dispatch
112
+ MultiJson.decode(get(@uri))
113
+ end
114
+
115
+ private
116
+
117
+ def get uri
118
+ Net::HTTP.get(uri)
119
+ end
120
+
121
+ end
122
+
123
+ class UnknownTypeError < StandardError; end
124
+
125
+ end
@@ -0,0 +1,21 @@
1
+ require 'bandcamp/methodical'
2
+
3
+ module Bandcamp
4
+ class Track
5
+
6
+ include Bandcamp::Methodical
7
+
8
+ def initialize attrs
9
+ to_methods attrs
10
+ end
11
+
12
+ def paid?
13
+ downloadable == 2 ? true : false
14
+ end
15
+
16
+ def free?
17
+ downloadable == 1 ? true : false
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Bandcamp
2
+ VERSION = "0.0.1"
3
+ end
data/lib/bandcamp.rb ADDED
@@ -0,0 +1,32 @@
1
+ require "bandcamp/request"
2
+ require "bandcamp/getter"
3
+ require "bandcamp/track"
4
+ require "bandcamp/configuration"
5
+ require "bandcamp/version"
6
+
7
+ module Bandcamp
8
+
9
+ def self.config
10
+ @configuration ||= Configuration.new
11
+ end
12
+
13
+ def self.get
14
+ request
15
+ end
16
+
17
+ def self.search band_name
18
+ request.search(band_name)
19
+ end
20
+
21
+ def self.resolve
22
+ request
23
+ end
24
+
25
+ private
26
+
27
+ def self.request
28
+ Getter.new(Request.new config.api_key)
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1 @@
1
+ require_relative './bandcamp'
@@ -0,0 +1,16 @@
1
+ require 'bandcamp/album'
2
+
3
+ module Bandcamp
4
+ describe Album do
5
+ describe ".new" do
6
+
7
+ it "accepts a hash and returns an Album" do
8
+ expect(Album.new(foo: "bar")).to be_an Album
9
+ end
10
+
11
+ it "creates methods based on the hash" do
12
+ expect(Album.new(foo: "bar").foo).to eq "bar"
13
+ end
14
+ end
15
+ end
16
+ end
data/spec/band_spec.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'bandcamp/band'
2
+
3
+ module Bandcamp
4
+ describe Band do
5
+ let(:band){Band.new(foo: "bar") }
6
+
7
+ it "mixes in Methodical" do
8
+ # passing in true here because to_methods is private
9
+ expect(band.respond_to?(:to_methods, true)).to be true
10
+ end
11
+
12
+ describe ".new" do
13
+ it "accepts a hash and returns a Band" do
14
+ expect(band).to be_a Band
15
+ end
16
+ it "creates methods based on the hash" do
17
+ expect(band.foo).to eq "bar"
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'bandcamp/band'
3
+ require 'bandcamp'
4
+
5
+ describe Bandcamp do
6
+
7
+ let(:getter) do
8
+ Class.new do
9
+ def search name
10
+ [Bandcamp::Band.new(foo: "bar"), Bandcamp::Band.new(fizz: "buzz")]
11
+ end
12
+ end.new
13
+ end
14
+
15
+ before(:each) { Bandcamp.config.api_key = "abc123" }
16
+
17
+ describe ".config" do
18
+ it 'returns a configuration object' do
19
+ expect(Bandcamp.config).to be_a (Bandcamp::Configuration)
20
+ end
21
+ end
22
+
23
+ describe ".get" do
24
+ it "returns an object for making requests" do
25
+ expect(Bandcamp.get).to be_a Bandcamp::Getter
26
+ end
27
+ end
28
+
29
+ describe ".search" do
30
+ it "accepts a band name to search for" do
31
+ Bandcamp.stub(:request).and_return(getter)
32
+ expect(Bandcamp.search "pitch black").to have(2).bands
33
+ end
34
+ end
35
+
36
+ describe ".resolve" do
37
+ it "returns an object for making requests" do
38
+ expect(Bandcamp.get).to be_a Bandcamp::Getter
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,23 @@
1
+ require 'bandcamp/configuration'
2
+
3
+ module Bandcamp
4
+ describe Configuration do
5
+
6
+ describe "#api_key" do
7
+
8
+ let(:config){ Configuration.new }
9
+
10
+ it "returns the key" do
11
+ config.api_key = "abc123"
12
+ expect(config.api_key).to eq "abc123"
13
+ end
14
+
15
+ context "when there is no key" do
16
+ it "raises an error" do
17
+ expect{ config.api_key }.to raise_error ConfigurationError
18
+ end
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1 @@
1
+ {"duration":713.4,"track_id":1784614291,"url":"/track/a-new-day-pitch-black-remix","lyrics":null,"large_art_url":"http://f0.bcbits.com/z/97/13/971382268-1.jpg","streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=af9ba8557731f9fef8cfea9d421b335d&id=1784614291&stream=1&ts=1357664814.0","title":"A New Day (Pitch Black Remix)","about":null,"album_id":405027664,"band_id":950934886,"credits":"Laya Project\r\n2010\r\nFirst released on \"A New Day - Laya Project Remixed\" (EarthSync)\r\nOriginal written by Patric Sebag + Yotam Agam\r\nPublished by EarthSync\r\nKindly licensed from EarthSync\r\nlayaproject.com","number":9,"small_art_url":"http://f0.bcbits.com/z/40/85/4085860-1.jpg","downloadable":2}
@@ -0,0 +1 @@
1
+ {"url":"http://pitchblack.bandcamp.com","name":"Pitch Black","offsite_url":"http://www.pitchblack.co.nz","subdomain":"pitchblack","band_id":950934886}
@@ -0,0 +1 @@
1
+ {"discography":[{"small_art_url":"http://f0.bcbits.com/z/14/53/1453962800-1.jpg","release_date":1264377600,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/harmonia-pt-i-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/16/25/1625598935-1.jpg","title":"Harmonia Pt.I EP","album_id":123407739,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/38/78/3878854390-1.jpg","release_date":1307923200,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/remixes-rarities?pk=284","large_art_url":"http://f0.bcbits.com/z/16/23/162338784-1.jpg","title":"Remixes & Rarities","album_id":405027664,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/32/90/3290360840-1.jpg","release_date":1220227200,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/1000-mile-drift-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/42/61/4261151524-1.jpg","title":"1000 Mile Drift EP","album_id":987436653,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/13/48/134898433-1.jpg","release_date":946684800,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/futureproof?pk=284","large_art_url":"http://f0.bcbits.com/z/29/12/2912181120-1.jpg","title":"Futureproof","album_id":1482002482,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/64/73/647374015-1.jpg","release_date":991353600,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/electronomicon?pk=284","large_art_url":"http://f0.bcbits.com/z/25/13/2513680008-1.jpg","title":"Electronomicon","album_id":1587432954,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/16/88/1688533909-1.jpg","release_date":1188604800,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/rude-mechanicals?pk=284","large_art_url":"http://f0.bcbits.com/z/25/63/256363587-1.jpg","title":"Rude Mechanicals","album_id":2119881068,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/13/32/1332099373-1.jpg","release_date":1149120000,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/empty-spaces-random-units-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/25/03/2503075126-1.jpg","title":"Empty Spaces, Random Units EP","album_id":2153042914,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/37/52/3752290706-1.jpg","release_date":1230768000,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/bird-soul-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/22/22/2222550128-1.jpg","title":"Bird Soul EP","album_id":2831814628,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/38/42/3842813731-1.jpg","release_date":1149033600,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/lost-in-trancelation-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/40/75/4075125765-1.jpg","title":"Lost in Trancelation EP","album_id":2844989968,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/16/46/1646703290-1.jpg","release_date":1228089600,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/rude-mechanicals-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/17/97/1797970339-1.jpg","title":"Rude Mechanicals EP","album_id":2898119910,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/21/22/2122942497-1.jpg","release_date":1086048000,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/ape-to-angel?pk=284","large_art_url":"http://f0.bcbits.com/z/96/40/96409743-1.jpg","title":"Ape to Angel","album_id":2909726980,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/36/68/3668138914-1.jpg","release_date":1264377600,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/harmonia-pt-ii-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/23/15/231526816-1.jpg","title":"Harmonia Pt.II EP","album_id":3220776887,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/29/23/2923271411-1.jpg","release_date":1241136000,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/rhythm-sound-movement?pk=284","large_art_url":"http://f0.bcbits.com/z/28/52/2852686826-1.jpg","title":"Rhythm, Sound & Movement","album_id":4038639624,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/15/93/1593128441-1.jpg","release_date":1117584000,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/flex-ep?pk=284","large_art_url":"http://f0.bcbits.com/z/24/65/246552663-1.jpg","title":"Flex EP","album_id":4040205273,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/37/15/3715147005-1.jpg","release_date":1117584000,"artist":"Pitch Black","downloadable":2,"url":"http://pitchblack.bandcamp.com/album/frequencies-fall?pk=284","large_art_url":"http://f0.bcbits.com/z/28/19/2819545390-1.jpg","title":"Frequencies Fall","album_id":4049890507,"band_id":950934886},{"small_art_url":"http://f0.bcbits.com/z/18/96/1896650809-1.jpg","release_date":1287532800,"artist":"Pitch Black","downloadable":1,"url":"http://pitchblack.bandcamp.com/album/live?pk=284","large_art_url":"http://f0.bcbits.com/z/20/80/2080879111-1.jpg","title":"Live","album_id":4079738343,"band_id":950934886}]}
@@ -0,0 +1 @@
1
+ {"credits":"Album Credits\r\n\r\n1. Te Po (Pitch Black Remix)\r\nHirini Melbourne and Richard Nunns \r\n2006\r\nFirst released on \"Te Whaiao: Te Ku Te Whe Remixed\"\r\nOriginal written by Hirini Melbourne and Richard Nunns \r\nPublished by Rattle Records\r\nKindly licensed from Rattle Records\r\nrattlerecords.net\r\n\r\n2. Kaikoura Dub (Original Demo)\r\nPitch Black\r\n2002\r\nUnreleased track that was featured in the film \"Whale Rider\"\r\nWritten and produced by Paddy Free and Michael Hodgson\r\nPublished by Native Tongue Music Publishing\r\nwhaleriderthemovie.co.nz\r\n\r\n3. House Of The Rising Dub (Pitch Black Remix)\r\nInternational Observer\r\n2009\r\nOriginal track written and produced by Tom Bailey\r\nPublished by Copyright Control/Native Tongue Music Publishing\r\nKindly licensed from Dubmission Records\r\nfacebook.com/internationalobserver\r\n\r\n4. For The Love Of It (Pitch Black Version) \r\nSalmonella Dub\r\n1999\r\nOriginal track written by Salmonella Dub\r\nPublished by Mushroom Music Publishing\r\nKindly licensed from Salmonella Dub \r\nsalmonelladub.com\r\n\r\n5. The Opaque (Pitch Black Remix)\r\nTom Cosm\r\n2011\r\nOriginal track written and produced by Tom Cosm\r\nPublished by Copyright Control\r\ncosm.co.nz\r\n\r\n6. Sensimillia (Pitch Black's Sensi Dub)\r\nKatchafire\r\n2006\r\nFirst released on \"Homegrown Dub\" (Mai Music)\r\nOrginal track written by Logan Bell, Jordan Bell, Jaimey Ferguson, Ara Adams-Tamatea and T Hohepa\r\nPublished by Local Music/Mushroom Music\r\nKindly licensed from Local Music\r\nkatchafire.co.nz\r\n\r\n7. I'm a Wanderer\r\nPitch Black\r\n1997\r\nThis is the first track we wrote together.\r\nOriginally released on the Curious Records compilation \"On the beat'n'track\"\r\nWritten and produced by Paddy Free and Michael Hodgson\r\nPublished by Native Tongue Music Publishing\r\n\r\n8. Mirror Beach (Pitch Black's Iron Sands Re-rub) \r\nMirror System\r\n2006\r\nOriginal written and produced by Steve Hillage, Miquette Giraudy and Mark Neal\r\nPublished by Stage Three Music/Copyright Control.\r\nKindly used by permission of Mirror System / A-Wave Records.\r\na-wave.com\r\n\r\n9. A New Day (Pitch Black Remix)\r\nLaya Project\r\n2010\r\nFirst released on \"A New Day - Laya Project Remixed\" (EarthSync)\r\nOriginal written by Patric Sebag + Yotam Agam\r\nPublished by EarthSync\r\nKindly licensed from EarthSync\r\nlayaproject.com\r\n\r\n10. Protect the Grain\r\nPitch Black\r\n2003\r\nFirst released on the limited edition \"Flex\" EP, created for our European excursion of 2003\r\nWritten and produced by Paddy Free and Michael Hodgson\r\nPublished by Native Tongue Music Publishing\r\n\r\n11. Past Present Future (Pitch Black's Sleep Whisperer Remix)\r\nTiki\r\n2009\r\nFirst released on \"Flux\" (TikiDub)\r\nOriginal written by Tiki and Inuwai Taanetinorau\r\nPublished by Tikidub Production\r\nKindly licensed from Tikidub Productions\r\ntikidub.com\r\n\r\n12. Disarray (Pitch Black's +13db@50Hz Remix)\r\nAcross Digital\r\n2011\r\nOriginal written by Rogerio Romao and Marcus Vandell \r\nacrossdigital.com\r\n\r\n13. For Your Digitalize Only ( Pitch Black Remix ) \r\nZen Lemonade\r\n2009 \r\nOriginal Written by Gus Till and Supercozi ( a.k.a Cozi Till Yukimi Yonezawa )\r\nPublished by Electronic Soundscapes \r\nKindly licensed from Electronic Soundscapes \r\nmyspace.com/zenlemonade\r\n\r\nDelf Movie\r\n1997\r\nWritten and directed by James Cunningham\r\nProduced by Paul Swadel\r\nMusic by Pitch Black\r\nnzfilm.co.nz\r\n\r\nArtwork by Nick Caro dub_badger@yahoo.co.uk\r\nMastering by Angus McNaughton @ Auralux Mastering","downloadable":2,"release_date":1307923200,"tracks":[{"credits":"Hirini Melbourne and Richard Nunns \r\n2006\r\nFirst released on \"Te Whaiao: Te Ku Te Whe Remixed\"\r\nOriginal written by Hirini Melbourne and Richard Nunns \r\nPublished by Rattle Records\r\nKindly licensed from Rattle Records\r\nrattlerecords.net","number":1,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=2868d777e70ccf799d1ea4ed8b72454c&id=2164488036&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Richard Nunns & Hirini Melbourne","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/26/86/2686072554-1.jpg","duration":307.147,"url":"/track/te-po-pitch-black-remix?pk=284","track_id":2164488036,"title":"Te Po (Pitch Black Remix)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/17/65/1765257345-1.jpg"},{"credits":"Pitch Black\r\n2002\r\nUnreleased track that was featured in the film \"Whale Rider\"\r\nWritten and produced by Paddy Free and Michael Hodgson\r\nPublished by Native Tongue Music Publishing\r\nwhaleriderthemovie.co.nz","number":2,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=8b80d2e659794deaafab782a728e98c7&id=1869822966&pk=284&stream=1&ts=1357780433.0","downloadable":2,"album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/50/77/507764963-1.jpg","duration":488.6,"url":"/track/kaikoura-dub?pk=284","track_id":1869822966,"title":"Kaikoura Dub","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/18/89/1889845170-1.jpg"},{"credits":"International Observer\r\n2009\r\nOriginal track written and produced by Tom Bailey\r\nPublished by Copyright Control/Native Tongue Music Publishing\r\nKindly licensed from Dubmission Records\r\nfacebook.com/internationalobserver","number":3,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=cfee3d69e10a36c24a6c0627cd9328b8&id=701130188&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"International Observer","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/32/99/3299308193-1.jpg","duration":378.067,"url":"/track/house-of-the-rising-dub-pitch-black-remix?pk=284","track_id":701130188,"title":"House of the Rising Dub (Pitch Black Remix)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/23/67/2367062797-1.jpg"},{"credits":"Salmonella Dub\r\n1999\r\nOriginal track written by Salmonella Dub\r\nPublished by Mushroom Music Publishing\r\nKindly licensed from Salmonella Dub \r\nsalmonelladub.com","number":4,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=a755646599f41b5d4b946aa28d63a1f3&id=1322997180&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Salmonella Dub","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/17/06/1706364830-1.jpg","duration":364.693,"url":"/track/for-the-love-of-it-pitch-black-version?pk=284","track_id":1322997180,"title":"For the Love of It (Pitch Black Version)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/12/05/1205071245-1.jpg"},{"credits":"Tom Cosm\r\n2011\r\nOriginal track written and produced by Tom Cosm\r\nPublished by Copyright Control\r\ncosm.co.nz","number":5,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=334c324361b20294053f27bb0cc4018c&id=3800662209&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Tom Cosm","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/36/99/3699358562-1.jpg","duration":446.933,"url":"/track/the-opaque-pitch-black-remix?pk=284","track_id":3800662209,"title":"The Opaque (Pitch Black Remix)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/17/00/1700900588-1.jpg"},{"credits":"Katchafire\r\n2006\r\nFirst released on \"Homegrown Dub\" (Mai Music)\r\nOrginal track written by Logan Bell, Jordan Bell, Jaimey Ferguson, Ara Adams-Tamatea and T Hohepa\r\nPublished by Local Music/Mushroom Music\r\nKindly licensed from Local Music\r\nkatchafire.co.nz","number":6,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=ee87f2604c9a2f8a136be8902242bc8b&id=2747346544&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Katchafire","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/30/39/3039059315-1.jpg","duration":243.227,"url":"/track/sensimillia-pitch-blacks-sensi-dub?pk=284","track_id":2747346544,"title":"Sensimillia (Pitch Black's Sensi Dub)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/34/85/3485112879-1.jpg"},{"credits":"Pitch Black\r\n1997\r\nThis is the first track we wrote together.\r\nOriginally released on the Curious Records compilation \"On the beat'n'track\"\r\nWritten and produced by Paddy Free and Michael Hodgson\r\nPublished by Native Tongue Music Publishing","number":7,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=61e20aa7e4bab6c114f4ba96df19f4de&id=3918113496&pk=284&stream=1&ts=1357780433.0","downloadable":2,"album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/15/18/1518822875-1.jpg","duration":364.12,"url":"/track/im-a-wanderer?pk=284","track_id":3918113496,"title":"I'm a Wanderer","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/14/62/1462051298-1.jpg"},{"credits":"Mirror System\r\n2006\r\nOriginal written and produced by Steve Hillage, Miquette Giraudy and Mark Neal\r\nPublished by Stage Three Music/Copyright Control.\r\nKindly used by permission of Mirror System / A-Wave Records.\r\na-wave.com","number":8,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=1b34b0b12382a607a74a17aee90acaaa&id=298836508&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Mirror System","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/87/92/879298162-1.jpg","duration":485.0,"url":"/track/mirror-beach-pitch-blacks-iron-sands-re-rub?pk=284","track_id":298836508,"title":"Mirror Beach (Pitch Black's Iron Sands Re-rub)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/27/42/2742882489-1.jpg"},{"credits":"Laya Project\r\n2010\r\nFirst released on \"A New Day - Laya Project Remixed\" (EarthSync)\r\nOriginal written by Patric Sebag + Yotam Agam\r\nPublished by EarthSync\r\nKindly licensed from EarthSync\r\nlayaproject.com","number":9,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=1b2d8bcc026ac92187e1c8db0c8b616d&id=1784614291&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Laya Project","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/23/52/2352771728-1.jpg","duration":713.4,"url":"/track/a-new-day-pitch-black-remix?pk=284","track_id":1784614291,"title":"A New Day (Pitch Black Remix)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/40/85/4085860-1.jpg"},{"credits":"Pitch Black\r\n2003\r\nFirst released on the limited edition \"Flex\" EP, created for our European excursion of 2003\r\nWritten and produced by Paddy Free and Michael Hodgson\r\nPublished by Native Tongue Music Publishing","number":10,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=6119547a154586894213322df46d1ca0&id=3919458311&pk=284&stream=1&ts=1357780433.0","downloadable":2,"album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/35/58/3558585391-1.jpg","duration":216.387,"url":"/track/protect-the-grain-2?pk=284","track_id":3919458311,"title":"Protect the Grain","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/79/14/791476813-1.jpg"},{"credits":"Tiki\r\n2009\r\nFirst released on \"Flux\" (TikiDub)\r\nOriginal written by Tiki and Inuwai Taanetinorau\r\nPublished by Tikidub Production\r\nKindly licensed from Tikidub Productions\r\ntikidub.com","number":11,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=7809ef04a78a08dbb23caed6cda2a849&id=122004781&pk=284&stream=1&ts=1357780433.0","downloadable":2,"artist":"Tiki","album_id":405027664,"large_art_url":"http://f0.bcbits.com/z/16/72/1672923578-1.jpg","duration":377.2,"url":"/track/past-present-future-pitch-blacks-sleep-whisperer-mix?pk=284","track_id":122004781,"title":"Past Present Future (Pitch Black's Sleep Whisperer Mix)","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/22/22/2222529058-1.jpg"},{"number":12,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=5237d1ef1ab87cae5a87ec8bc9cfc946&id=1821566106&pk=284&stream=1&ts=1357780433.0","artist":"Across Digital","album_id":405027664,"duration":473.836,"url":"/track/disarray-pitch-blacks-13db-50hz-remix?pk=284","track_id":1821566106,"title":"Disarray (Pitch Black's +13db@50Hz Remix)","band_id":950934886},{"number":13,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=29e25af0df2cffbac79038204d07c96e&id=3372180985&pk=284&stream=1&ts=1357780433.0","artist":"Zen Lemonade","album_id":405027664,"duration":339.614,"url":"/track/for-your-digitalize-only-pitch-black-remix?pk=284","track_id":3372180985,"title":"For Your Digitalize Only ( Pitch Black Remix )","about":"For Your Digitalize Only ( Pitch Black Remix ) \r\nZen Lemonade\r\n2009\r\nOriginal Written by Gus Till and Supercozi ( a.k.a Cozi Till Yukimi Yonezawa )\r\nPublished by Electronic Soundscapes \r\nKindly licensed from Electronic Soundscapes \r\nwww.myspace.com/zenlemonade","band_id":950934886}],"large_art_url":"http://f0.bcbits.com/z/16/23/162338784-1.jpg","album_id":405027664,"url":"http://pitchblack.bandcamp.com/album/remixes-rarities?pk=284","title":"Remixes & Rarities","about":"Remixes and Rarities – the latest album from Auckland’s Pitch Black – is a package of rare tracks and lovingly crafted remixes of other artists’ music, chosen by Paddy Free and Mike Hodgson to represent their fifteen year reign as Aotearoa’s favourite electronica act.\r\n\r\nKnown globally for their stomping, genre defying live sets, Remixes and Rarities showcases Pitch Black’s mellower side, the one that also makes them favourites in the living room. The album begins with the call of the kōauau (Māori flute), the intro to a dancefloor friendly, but respectful reworking of the Richard Nunns and Hirini Melbourne original, ‘Te Po’ and ends with an equally haunting version of Tiki’s ‘Past Present Future’. Bookended by these distinctively local soundscapes, Remixes and Rarities represents the past, present and future of the Pitch Black partnership.\r\n\r\nIncluded in the remixes are tracks by fellow Aotearoa/NZ dub trailblazers International Observer (‘House of the Rising Dub’) and Salmonella Dub (‘For the Love of It’), along with ‘The Opaque’ by independent music producer Tom Cosm, and ‘Sensimillia’ by reggae legends Katchafire – all fed through the PB warping machine. Representing from further a field is ‘Mirror Beach’ by Mirror System (the ambient project of Britain’s System 7), and ‘A New Day’, a remix of a Sri Lankan track that Pitch Black remixed for the Laya Project, a collaboration of regional folk musicians affected by the 2004 tsunami.\r\n\r\nFor Mike, the remix process is a chance to share creativity: “We love getting other artists to remix our tunes and we really enjoy remixing others’ music. It gives us a chance to play with different types of sounds and composing techniques. I love getting the parts of these songs and creating a folder of sounds in response to the track. This quite often gives us the sound field and sonic vibe for the remix.”\r\n\r\nWhilst all of Pitch Black’s four studio albums have been followed by a compilation of versions by local and international artists, this is the first to showcase their own remixing output, and Mike and Paddy enjoyed the process of going back over all the old dats.\r\n\r\n“From 1996 to 2011 we have had many chances to remix other artists’ songs, and these have been released on a variety of albums and compilations around the world – this Pitch Black release gives us a chance to put them all in one place. It contains tracks from the very beginning of us working together right up to a track finished earlier this year,” says Paddy.\r\n\r\nIncluded on the album are three Pitch Black originals that were either never released or were on compilations or short limited runs. Purists will love the inclusion of 1996’s ‘I’m a Wanderer’, the first track the pair worked on together.\r\n\r\n“I had a long drums and effects jam that I wanted to turn into a song and Paddy was keen to work together so we took this long evolving track and chopped it up into a structure and then added Paddy’s vibe to it,” remembers Mike. “Pitch Black was born.”\r\n\r\n‘I’m a Wanderer’ showcases the industrial beginnings of what would become the Pitch Black sound – a dynamic balancing act between heavily sculpted basslines and choppy melody that has been acknowledged by many as an evocative soundtrack to the Aotearoa landscape. In contrast, the pastoral ‘Protect the Grain’, a windborne ambient track released on the limited edition EP Flex around the time of widespread anti-GE demonstrations, represents Pitch Black at their gentlest.\r\n\r\nAlso included is ‘Kaikoura Dub’, a previously unreleased track from which a snippet was used on Whalerider to accompany Paikea’s journey away from her village, during the scene when she heard the whales calling her home.\r\n\r\nMike explains how the collaboration came about: “In 2000 I bumped into Niki Caro and she asked if we had any tunes lying around that she could use for Whalerider. We had just come back from a session in Kaikoura where we had jammed a new track into a long 23min mix. I put that on CD for her and she ended up choosing a sliver for the film. We subsequently used the bones of this track for the tune ‘Elements Turn’ on Ape to Angel but it’s great to find the original two track recording and release it.”\r\n\r\nPitch Black have always been more than a dance act, but on Remixes and Rarities they demonstrate the full reach of the musical territory they love to explore.","band_id":950934886,"small_art_url":"http://f0.bcbits.com/z/38/78/3878854390-1.jpg"}
@@ -0,0 +1 @@
1
+ {"results":[{"url":"http://pitchblackk.bandcamp.com","subdomain":"pitchblackk","name":"Pitch Black","band_id":12800984,"offsite_url":null},{"url":"http://pitchblackattack.bandcamp.com","subdomain":"pitchblackattack","name":"Pitch Black","band_id":168853150,"offsite_url":"http://www.pitch-black.us"},{"url":"http://pitchblack1.bandcamp.com","subdomain":"pitchblack1","name":"Pitch Black","band_id":181856001,"offsite_url":null},{"url":"http://pitchblack.bandcamp.com","subdomain":"pitchblack","name":"Pitch Black","band_id":950934886,"offsite_url":"http://www.pitchblack.co.nz"},{"url":"http://pitchblack5.bandcamp.com","subdomain":"pitchblack5","name":"PITCH BLACK","band_id":2607764567,"offsite_url":null}]}
@@ -0,0 +1 @@
1
+ {"results":[]}
@@ -0,0 +1 @@
1
+ {"1735088360":{"number":1,"lyrics":null,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=668fdf0d155050f14b3e9193f55cd6e1&id=1735088360&stream=1&ts=1358548398.0","duration":512.779,"track_id":1735088360,"url":"/track/evolution-1-1","large_art_url":null,"title":"Evolution 1:1","small_art_url":null,"about":null,"album_id":171685143,"band_id":1908050684,"downloadable":2,"credits":"(C) & (P) 2012 Ultimae"},"1739611553":{"number":2,"lyrics":null,"streaming_url":"http://popplers5.bandcamp.com/download/track?enc=mp3-128&fsig=c5981223e0c6e724f8c051405ee09dbf&id=1739611553&stream=1&ts=1358548398.0","duration":440.0,"track_id":1739611553,"url":"/track/emoxygen","large_art_url":null,"title":"Emoxygen","small_art_url":null,"about":null,"album_id":165628809,"band_id":1589471525,"downloadable":2,"credits":null}}
@@ -0,0 +1 @@
1
+ {"error":true,"error_message":"unknown band"}
@@ -0,0 +1 @@
1
+ {"discography":[]}
@@ -0,0 +1 @@
1
+ {"error":true,"error_message":"unknown url"}
@@ -0,0 +1 @@
1
+ {"band_id":950934886}
@@ -0,0 +1,165 @@
1
+ require 'bandcamp/getter'
2
+ require 'bandcamp/request'
3
+ require 'bandcamp/track'
4
+ require 'bandcamp/album'
5
+
6
+ module Bandcamp
7
+ describe Getter do
8
+
9
+ let(:request) do
10
+ Class.new do
11
+
12
+ def track id
13
+ case
14
+ when id.to_s.include?("1111")
15
+ nil
16
+ when id.to_s.include?(',')
17
+ json = File.read(File.join %w(spec fixtures tracks.json))
18
+ MultiJson.decode json
19
+ else
20
+ json = File.read(File.join %w(spec fixtures a_new_day.json))
21
+ MultiJson.decode json
22
+ end
23
+ end
24
+
25
+ def band name
26
+ return nil if name == 111111
27
+ json = File.read(File.join %w(spec fixtures pitch_black_band.json))
28
+ MultiJson.decode json
29
+ end
30
+
31
+ def album id
32
+ return nil if id == 1111
33
+ json = File.read(File.join %w(spec fixtures remixes_and_rarities_album.json))
34
+ MultiJson.decode json
35
+ end
36
+
37
+ def search name
38
+ return nil if name == "Foo and the Bars"
39
+ json = File.read(File.join %w(spec fixtures search.json))
40
+ MultiJson.decode(json)["results"]
41
+ end
42
+
43
+ def url bandcamp_url
44
+ case bandcamp_url
45
+ when "http://pitchblack.bandcamp.com/"
46
+ {"band_id"=>950934886}
47
+ when "http://pitchblack.bandcamp.com/track/a-new-day-pitch-black-remix"
48
+ {"band_id" => 950934886,"track_id" => 1784614291}
49
+ when "http://interchill.bandcamp.com/album/power-salad"
50
+ {"band_id"=>1589471525, "album_id"=>165628809}
51
+ else
52
+ nil
53
+ end
54
+
55
+ end
56
+
57
+ end.new
58
+
59
+ end
60
+
61
+ let(:getter){ Getter.new request }
62
+
63
+ describe ".new" do
64
+ it "takes a request object" do
65
+ expect(Getter.new(request)).to be_a Getter
66
+ end
67
+ end
68
+
69
+ describe "#track" do
70
+ context "when passed a track id" do
71
+ it "returns a Track" do
72
+ expect(getter.track(1784614291)).to be_a Track
73
+ end
74
+
75
+ it "returns nil if nothing is found" do
76
+ expect(getter.track 1111).to be_nil
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#album" do
82
+ context "when the album exists" do
83
+ it "returns an album" do
84
+ expect(getter.album(405027664)).to be_an Album
85
+ end
86
+ end
87
+
88
+ context "when the album does not exist" do
89
+ it "returns nil" do
90
+ expect(getter.album(1111)).to be_nil
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+ describe "#tracks" do
97
+ context "when given an array of track ids" do
98
+ it "returns an array of tracks" do
99
+ expect(getter.tracks 1735088360, 1739611553).to have(2).tracks
100
+ end
101
+ end
102
+
103
+ context "when no tracks are found" do
104
+ it "returns an empty array" do
105
+ expect(getter.tracks(1111,1111)).to eq []
106
+ end
107
+ end
108
+ end
109
+
110
+ describe "#search" do
111
+ context "when given a band name" do
112
+ it "returns an array of Band objects" do
113
+ expect(getter.search "pitch black").to have(5).bands
114
+ end
115
+ end
116
+ context "when no results are found" do
117
+ it "returns an empty array" do
118
+ expect(getter.search "Foo and the Bars").to eq []
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#band" do
124
+ context "when given a band name" do
125
+ it "returns a Band object" do
126
+ expect(getter.band(950934886).name).to eq "Pitch Black"
127
+ end
128
+ end
129
+
130
+ context "when no band is found" do
131
+ it "returns nil" do
132
+ expect(getter.band(111111)).to be_nil
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "#url" do
138
+ context "when given a track url" do
139
+ it "returns a Track" do
140
+ expect(getter.url "http://pitchblack.bandcamp.com/track/a-new-day-pitch-black-remix" ).to be_a Track
141
+ end
142
+ end
143
+
144
+ context "when given a band url" do
145
+ it "returns a band" do
146
+ expect(getter.url "http://pitchblack.bandcamp.com/").to be_a Band
147
+ end
148
+ end
149
+
150
+ context "when given an album url" do
151
+ it "returns an album" do
152
+ expect(getter.url "http://interchill.bandcamp.com/album/power-salad").to be_an Album
153
+ end
154
+ end
155
+
156
+ context "when given a bad url" do
157
+ it "returns nil" do
158
+ expect(getter.url 11111).to be_nil
159
+ end
160
+ end
161
+
162
+ end
163
+
164
+ end
165
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'bandcamp/methodical'
3
+
4
+ module Bandcamp
5
+
6
+ describe Methodical do
7
+
8
+ let(:klass) do
9
+ Class.new do
10
+
11
+ include Methodical
12
+
13
+ def initialize hash
14
+ to_methods hash
15
+ end
16
+
17
+ end
18
+ end
19
+ let(:data){ {foo: "bar"} }
20
+
21
+ describe "#to_methods" do
22
+
23
+ it "creates instance methods from a hash" do
24
+ expect(klass.new(data).public_methods).to include(:foo)
25
+ end
26
+
27
+ it "is a private method" do
28
+ expect(klass.new(data).private_methods).to include(:to_methods)
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,206 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+ require 'bandcamp/request'
3
+
4
+ module Bandcamp
5
+ describe Request do
6
+
7
+ let(:request){ Request.new "1234" }
8
+ let(:track_json){ File.read(File.join(%w(spec fixtures a_new_day.json))) }
9
+ let(:album_json){ File.read(File.join(%w(spec fixtures remixes_and_rarities_album.json))) }
10
+ let(:band_json){ File.read(File.join(%w(spec fixtures pitch_black_band.json))) }
11
+ let(:discography_json){ File.read(File.join(%w(spec fixtures pitch_black_discography.json))) }
12
+ let(:unknown_band_json){ File.read(File.join(%w(spec fixtures unknown_band.json))) }
13
+ let(:unknown_band_discography_json){ File.read(File.join(%w(spec fixtures unknown_band_discography.json))) }
14
+ let(:url_json){ File.read(File.join(%w(spec fixtures url.json))) }
15
+ let(:url_error_json){ File.read(File.join(%w(spec fixtures unknown_url.json))) }
16
+
17
+ let(:search_json){ File.read(File.join(%w(spec fixtures search.json))) }
18
+ let(:no_results_json){ File.read(File.join(%w(spec fixtures search_no_results.json))) }
19
+
20
+ describe '#initialize' do
21
+ it 'sets the base uri' do
22
+ expect(request.host).to eq "api.bandcamp.com"
23
+ end
24
+
25
+ it "is instantiated with an API key" do
26
+ r = Request.new "abc123"
27
+ expect(r.api_key).to eq "abc123"
28
+ end
29
+ end
30
+
31
+ describe '#uri' do
32
+ it 'returns the completed uri' do
33
+ expect(request.uri).to eq 'http://api.bandcamp.com'
34
+ end
35
+ end
36
+
37
+ describe '#path' do
38
+ it 'allows setting an arbitrary path' do
39
+ request.path = '/foo'
40
+ expect(request.path).to eq "/foo"
41
+ end
42
+
43
+ it 'rejects craziness' do
44
+ expect {request.path = '@!#%^$+*(&' }.to raise_error(URI::InvalidComponentError)
45
+ end
46
+
47
+ end
48
+
49
+ describe '#type' do
50
+ # types include: band, album, track, discography, url
51
+ context "when type is discography" do
52
+ it "sets the path accordingly" do
53
+ request.type :discography
54
+ expect(request.path).to eq "/api/band/3/discography"
55
+ end
56
+ end
57
+
58
+ context "when type is url" do
59
+ it "sets the path accordingly" do
60
+ request.type :url
61
+ expect(request.path).to eq '/api/url/1/info'
62
+ end
63
+ end
64
+
65
+ it 'raises an error for unrecognized types' do
66
+ expect{ request.type(:foo) }.to raise_error(UnknownTypeError)
67
+ end
68
+
69
+ end
70
+
71
+ describe '#query' do
72
+ it 'creates a query string from a hash' do
73
+ Bandcamp.config.api_key = '1234'
74
+ request.query = {name: "pitch black", album: "ape to angel"}
75
+ expect(request.query).to eq "key=1234&name=pitch%20black&album=ape%20to%20angel"
76
+ end
77
+ end
78
+
79
+ it 'builds a uri' do
80
+ Bandcamp.config.api_key = 1234
81
+ request.type :track
82
+ request.query= {track_id: 1784614291}
83
+ expect(request.uri).to eq "http://api.bandcamp.com/api/track/3/info?key=1234&track_id=1784614291"
84
+ end
85
+
86
+ describe "#track" do
87
+ it "requests the correct uri" do
88
+ uri = URI("http://api.bandcamp.com/api/track/3/info?key=1234&track_id=1784614291")
89
+ request.should_receive(:get).with(uri).and_return(track_json)
90
+ request.track(1784614291)
91
+ end
92
+
93
+ it "returns a hash of track attributes" do
94
+ request.stub(:get).and_return(track_json)
95
+ expect(request.track(1784614291)).to be_a Hash
96
+ end
97
+
98
+ context "when track does not exist" do
99
+ it "returns nil" do
100
+ request.stub(:get).and_return("{}")
101
+ expect(request.track(11111)).to be_nil
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ describe "#album" do
108
+ it "requests the correct url" do
109
+ uri = URI("http://api.bandcamp.com/api/album/2/info?key=1234&album_id=405027664")
110
+ request.should_receive(:get).with(uri).and_return(album_json)
111
+ request.album(405027664)
112
+ end
113
+
114
+ it "returns a hash of album attributes" do
115
+ request.stub(:get).and_return(album_json)
116
+ expect(request.album(405027664)).to be_a Hash
117
+ end
118
+
119
+ context "when album does not exist" do
120
+ it "returns nil" do
121
+ request.stub(:get).and_return("{}")
122
+ expect(request.album(11111)).to be_nil
123
+ end
124
+ end
125
+ end
126
+
127
+ describe "#band" do
128
+ it "requests the proper uri" do
129
+ uri = URI("http://api.bandcamp.com/api/band/3/info?key=1234&band_id=950934886")
130
+ request.should_receive(:get).with(uri).and_return(band_json)
131
+ request.band(950934886)
132
+ end
133
+
134
+ it "returns a hash of band attributes" do
135
+ request.stub(:get).and_return(band_json)
136
+ expect(request.band(950934886)).to be_a Hash
137
+ end
138
+
139
+ it 'returns nil when no band is found' do
140
+ request.stub(:get).and_return(unknown_band_json)
141
+ expect(request.band(1234)).to eq nil
142
+ end
143
+ end
144
+
145
+ describe "#url" do
146
+ it "returns a hash of ids" do
147
+ request.stub(:get).and_return(url_json)
148
+ expect(request.url("pitchblack.bandcamp.com")).to be_a Hash
149
+ end
150
+ it "requests the proper uri" do
151
+ uri = URI("http://api.bandcamp.com/api/url/1/info?key=1234&url=pitchblack.bandcamp.com")
152
+ request.should_receive(:get).with(uri).and_return(url_json)
153
+ request.url "pitchblack.bandcamp.com"
154
+ end
155
+ it "returns nil for unknown uris" do
156
+ uri = URI("http://api.bandcamp.com/api/url/1/info?key=1234&url=foo")
157
+ request.should_receive(:get).with(uri).and_return(url_error_json)
158
+ expect(request.url "foo").to be_nil
159
+ end
160
+ end
161
+
162
+ describe "#search" do
163
+ it "requests the proper uri" do
164
+ uri = URI("http://api.bandcamp.com/api/band/3/search?key=1234&name=pitch%20black")
165
+ request.should_receive(:get).with(uri).and_return(search_json)
166
+ request.search("pitch black")
167
+ end
168
+
169
+ it "returns an array of hashes" do
170
+ request.stub(:get).and_return(search_json)
171
+ expect(request.search("pitch black")).to be_an Array
172
+ end
173
+
174
+ it 'returns nil when no results are found' do
175
+ request.stub(:get).and_return(no_results_json)
176
+ expect(request.search("foo")).to eq nil
177
+ end
178
+ end
179
+
180
+ describe "#discography" do
181
+ it "requests the proper uri" do
182
+ uri = URI("http://api.bandcamp.com/api/band/3/discography?key=1234&band_id=950934886")
183
+ request.should_receive(:get).with(uri).and_return(discography_json)
184
+ request.discography(950934886)
185
+ end
186
+
187
+ it "returns an array of hashes" do
188
+ request.stub(:get).and_return(discography_json)
189
+ expect(request.discography(950934886)).to be_an Array
190
+ end
191
+
192
+ it 'returns nil when no discography is found' do
193
+ request.stub(:get).and_return(unknown_band_discography_json)
194
+ expect(request.discography(1234)).to eq nil
195
+ end
196
+ end
197
+
198
+ describe "#dispatch" do
199
+ it "calls get with a URI object" do
200
+ request.should_receive(:get).with(kind_of(URI)).and_return(band_json)
201
+ request.band 950934886
202
+ end
203
+ end
204
+
205
+ end
206
+ end
@@ -0,0 +1 @@
1
+ $:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'bandcamp/track'
3
+ require 'multi_json'
4
+
5
+ module Bandcamp
6
+
7
+ describe Track do
8
+
9
+ it "includes Bandcamp::Methodical" do
10
+ expect(Track.ancestors).to include(Bandcamp::Methodical)
11
+ end
12
+
13
+ let(:track_json){ MultiJson.decode(File.read(File.join %w(spec fixtures a_new_day.json))) }
14
+ let(:track){Track.new(track_json)}
15
+
16
+ describe "#new" do
17
+
18
+ it "is called with a hash" do
19
+ Track.should_receive(:new).with(instance_of Hash)
20
+ track
21
+ end
22
+
23
+ it "creates reader methods from keys and values" do
24
+ expect(track.track_id).to eq 1784614291
25
+ end
26
+
27
+ end
28
+
29
+ describe "#paid?" do
30
+ it "tells you if the track is paid or not" do
31
+ expect(track.paid?).to eq true
32
+ end
33
+ end
34
+
35
+ describe "#free?" do
36
+ it "tells you if the track is free or not" do
37
+ expect(track.free?).to eq false
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bandcamp_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Williamson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: A helper library for accessing the Bandcamp.com api
47
+ email:
48
+ - blessedbyvirtuosity@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - bandcamp_api.gemspec
60
+ - lib/bandcamp.rb
61
+ - lib/bandcamp/album.rb
62
+ - lib/bandcamp/band.rb
63
+ - lib/bandcamp/configuration.rb
64
+ - lib/bandcamp/getter.rb
65
+ - lib/bandcamp/methodical.rb
66
+ - lib/bandcamp/request.rb
67
+ - lib/bandcamp/track.rb
68
+ - lib/bandcamp/version.rb
69
+ - lib/bandcamp_api.rb
70
+ - spec/album_spec.rb
71
+ - spec/band_spec.rb
72
+ - spec/bandcamp_spec.rb
73
+ - spec/configuration_spec.rb
74
+ - spec/fixtures/a_new_day.json
75
+ - spec/fixtures/pitch_black_band.json
76
+ - spec/fixtures/pitch_black_discography.json
77
+ - spec/fixtures/remixes_and_rarities_album.json
78
+ - spec/fixtures/search.json
79
+ - spec/fixtures/search_no_results.json
80
+ - spec/fixtures/tracks.json
81
+ - spec/fixtures/unknown_band.json
82
+ - spec/fixtures/unknown_band_discography.json
83
+ - spec/fixtures/unknown_url.json
84
+ - spec/fixtures/url.json
85
+ - spec/getter_spec.rb
86
+ - spec/methodic_spec.rb
87
+ - spec/request_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/track_spec.rb
90
+ homepage:
91
+ licenses: []
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.24
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: A library for communicating with the Bandcamp.com api and wrapping the various
114
+ types of data to make it easier to work with.
115
+ test_files:
116
+ - spec/album_spec.rb
117
+ - spec/band_spec.rb
118
+ - spec/bandcamp_spec.rb
119
+ - spec/configuration_spec.rb
120
+ - spec/fixtures/a_new_day.json
121
+ - spec/fixtures/pitch_black_band.json
122
+ - spec/fixtures/pitch_black_discography.json
123
+ - spec/fixtures/remixes_and_rarities_album.json
124
+ - spec/fixtures/search.json
125
+ - spec/fixtures/search_no_results.json
126
+ - spec/fixtures/tracks.json
127
+ - spec/fixtures/unknown_band.json
128
+ - spec/fixtures/unknown_band_discography.json
129
+ - spec/fixtures/unknown_url.json
130
+ - spec/fixtures/url.json
131
+ - spec/getter_spec.rb
132
+ - spec/methodic_spec.rb
133
+ - spec/request_spec.rb
134
+ - spec/spec_helper.rb
135
+ - spec/track_spec.rb