band_page 0.0.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/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bandpage.gemspec
4
+ gemspec
5
+ gem 'rspec'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 James Brennan
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,25 @@
1
+ # BandPage
2
+
3
+ A ruby wrapper for the BandPage API.
4
+
5
+ ## Installation
6
+
7
+ Add this to your gemfile:
8
+
9
+ gem 'band_page'
10
+
11
+
12
+
13
+ ## Usage
14
+
15
+ TODO: Write usage instructions here
16
+
17
+ ## Contributing
18
+
19
+ Contributions are welcome and encouraged. Please write specs for any changes that you would like merged. Thanks!
20
+
21
+ 1. Fork it
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
24
+ 4. Push to the branch (`git push origin my-new-feature`)
25
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bandpage.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'band_page/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "band_page"
8
+ gem.version = BandPage::VERSION
9
+ gem.authors = ["James Brennan"]
10
+ gem.email = ["james@carbonfive.com", "brennanmusic@gmail.com"]
11
+ gem.description = 'Wrapper for BandPage API'
12
+ gem.summary = 'Wrapper for BandPage API - https://developers.bandpage.com/docs'
13
+ gem.homepage = "https://github.com/jamesBrennan/bandpage_api"
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
+
20
+ gem.add_dependency('httparty')
21
+ gem.add_dependency('recursive-open-struct')
22
+ gem.add_development_dependency('fakeweb')
23
+ end
data/lib/band_page.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "band_page/version"
2
+ require "band_page/config"
3
+ require "band_page/token"
4
+ require "band_page/client"
5
+
6
+ module BandPage
7
+ class AuthorizationError < StandardError; end
8
+ class ResourceNotFoundError < StandardError; end
9
+ class ServerError < StandardError; end
10
+ class ServiceUnavailableError < StandardError; end
11
+ end
@@ -0,0 +1,86 @@
1
+ require 'httparty'
2
+ require 'recursive-open-struct'
3
+
4
+ module BandPage
5
+ class Client
6
+ CONNECTIONS = [:emails, :events, :genres, :tracks, :photos, :videos, :websites]
7
+ BASE_URL = 'https://api-read.bandpage.com/'
8
+
9
+ attr_accessor :config, :token
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ def band
15
+ get
16
+ end
17
+
18
+ def method_missing(m, *args, &block)
19
+ return get(m) if CONNECTIONS.include?(m)
20
+ super
21
+ end
22
+
23
+ private
24
+
25
+ def authenticate
26
+ resp = HTTParty.post("#{BASE_URL}/token",
27
+ basic_auth: {
28
+ username: config.client_id,
29
+ password: config.secret_key
30
+ },
31
+ query: {
32
+ client_id: config.client_id,
33
+ grant_type: 'client_credentials'
34
+ })
35
+ if [200, 202].include? resp.code
36
+ @token = BandPage::Token.new(resp['access_token'], resp['expires_in'])
37
+ else
38
+ error_response resp
39
+ end
40
+ end
41
+
42
+ def get(connection = nil)
43
+ authenticate if @token.nil? || @token.expired?
44
+ resp = HTTParty.get(url(connection), headers:
45
+ {"Authorization" => "Bearer #{@token.string}"}
46
+ )
47
+ if [200, 202].include? resp.code
48
+ return resp if connection.nil?
49
+ load_response_objects resp
50
+ else
51
+ error_response resp
52
+ end
53
+ end
54
+
55
+ def load_response_objects(response)
56
+ response.parsed_response.map do |obj|
57
+ RecursiveOpenStruct.new(obj)
58
+ end
59
+ end
60
+
61
+ def error_response(resp)
62
+ raise case resp.code
63
+ when 401
64
+ BandPage::AuthorizationError
65
+ when 404
66
+ BandPage::ResourceNotFoundError
67
+ when 500
68
+ BandPage::ServerError.new resp['error']
69
+ else
70
+ StandardError.new("An unknown error occurred when attempting to parse: #{resp.inspect}")
71
+ end
72
+ end
73
+
74
+ def url(connection)
75
+ connection.nil? ? band_url : "#{band_url}/#{connection}"
76
+ end
77
+
78
+ def band_url
79
+ @band_url ||= "#{BASE_URL}/#{bid}"
80
+ end
81
+
82
+ def bid
83
+ config.band_id
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,14 @@
1
+ # Config object which exists primarily to document the
2
+ # information needed to interact with the BandPage API
3
+ module BandPage
4
+ class Config
5
+ attr_accessor :app_id, :client_id, :secret_key, :band_id
6
+
7
+ def initialize(conf)
8
+ @app_id = conf[:app_id]
9
+ @client_id = conf[:client_id]
10
+ @secret_key = conf[:secret_key]
11
+ @band_id = conf[:band_id]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module BandPage
2
+ class Token
3
+ attr_accessor :expires_at, :string
4
+ def initialize(string, expires_in)
5
+ @string = string
6
+ @expires_at = Time.now + expires_in.to_i
7
+ end
8
+
9
+ def expired?
10
+ @expires_at < Time.now
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module BandPage
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ module BandPage
2
+ module RecordedApiResponses
3
+ def self.tracks
4
+ "HTTP/1.1 200 OK\r\nContent-Type: application/json;charset=UTF-8\r\nDate: Tue, 05 Mar 2013 23:06:07 GMT\r\nLink: <https://api-read.bandpage.com/164527841654870016/tracks?offset=50&access_token=AAAAAQAAAAECluDXQ8JgAAKW4NcngmAAApbgKZSCMAAAAAAAAAAAAAAAAT09BFezUoRLKkkXgLrchDm6DOYYA0tY5K0=>;rel=\"next\";type=\"application/json\";title=\"Next Results\"\r\nServer: Apache-Coyote/1.1\r\nContent-Length: 2241\r\nConnection: keep-alive\r\n\r\n[{\"albumArt\":{\"original\":{\"source\":\"https://i1.sndcdn.com/artworks-000037081241-3xfo2g-large.jpg?923db0b\",\"width\":0,\"height\":0},\"large\":{\"source\":\"https://i1.sndcdn.com/artworks-000037081241-3xfo2g-large.jpg?923db0b\",\"width\":0,\"height\":0},\"small\":{\"source\":\"https://i1.sndcdn.com/artworks-000037081241-3xfo2g-large.jpg?923db0b\",\"width\":0,\"height\":0},\"thumb\":{\"source\":\"https://i1.sndcdn.com/artworks-000037081241-3xfo2g-large.jpg?923db0b\",\"width\":0,\"height\":0}},\"artworkUrl\":\"\",\"bid\":\"164528215925219328\",\"downloadCount\":\"0\",\"downloadUrl\":\"\",\"downloadable\":false,\"duration\":\"149617\",\"permalinkUrl\":\"http://soundcloud.com/james-the-giant/long-days-of-longing\",\"playCount\":\"97\",\"provider\":\"soundcloud\",\"providerId\":\"72769600\",\"purchasable\":false,\"purchaseUrl\":\"\",\"streamUrl\":\"http://api.soundcloud.com/tracks/72769600/stream?secret_token=s-JiJNd&consumer_key=P0OieYzyPHtoHulKAJOjlA\",\"title\":\"Long Days of Longing\",\"type\":\"Track\"},{\"albumArt\":{\"original\":{\"source\":\"\",\"width\":0,\"height\":0},\"large\":{\"source\":\"\",\"width\":0,\"height\":0},\"small\":{\"source\":\"\",\"width\":0,\"height\":0},\"thumb\":{\"source\":\"\",\"width\":0,\"height\":0}},\"artworkUrl\":\"\",\"bid\":\"164528200733437952\",\"downloadCount\":\"0\",\"downloadUrl\":\"\",\"downloadable\":false,\"duration\":\"185982\",\"permalinkUrl\":\"http://soundcloud.com/james-the-giant/wave-hello-wave-goodbye\",\"playCount\":\"79\",\"provider\":\"soundcloud\",\"providerId\":\"72770796\",\"purchasable\":false,\"purchaseUrl\":\"\",\"streamUrl\":\"http://api.soundcloud.com/tracks/72770796/stream?secret_token=s-Z07gg&consumer_key=P0OieYzyPHtoHulKAJOjlA\",\"title\":\"Wave Hello, Wave Goodbye\",\"type\":\"Track\"},{\"albumArt\":{\"original\":{\"source\":\"\",\"width\":0,\"height\":0},\"large\":{\"source\":\"\",\"width\":0,\"height\":0},\"small\":{\"source\":\"\",\"width\":0,\"height\":0},\"thumb\":{\"source\":\"\",\"width\":0,\"height\":0}},\"artworkUrl\":\"\",\"bid\":\"165717578767949824\",\"downloadCount\":\"0\",\"downloadUrl\":\"\",\"downloadable\":false,\"duration\":\"181462\",\"permalinkUrl\":\"http://soundcloud.com/james-the-giant/seven-secret-words\",\"playCount\":\"52\",\"provider\":\"soundcloud\",\"providerId\":\"73134819\",\"purchasable\":false,\"purchaseUrl\":\"\",\"streamUrl\":\"http://api.soundcloud.com/tracks/73134819/stream?secret_token=s-njzbu&consumer_key=P0OieYzyPHtoHulKAJOjlA\",\"title\":\"Seven Secret Words\",\"type\":\"Track\"}]"
5
+ end
6
+
7
+ def self.authenticate
8
+ "HTTP/1.1 200 OK\r\nContent-Type: application/json;charset=UTF-8\r\nDate: Wed, 06 Mar 2013 00:18:51 GMT\r\nServer: Apache-Coyote/1.1\r\nContent-Length: 151\r\nConnection: keep-alive\r\n\r\n{\"access_token\":\"AAAAAQAAAAECluDXQ8JgAAKW4NcngmAAApbgKZSCMAAAAAAAAAAAAAAAAT09R4rH6yW52T8rDPD3C__Hnl-O6Bw5MtM=\",\"token_type\":\"bearer\",\"expires_in\":3600}"
9
+ end
10
+
11
+ def self.server_error
12
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json;charset=ISO-8859-1\r\nDate: Wed, 06 Mar 2013 01:05:13 GMT\r\nServer: Apache-Coyote/1.1\r\nContent-Length: 241\r\nConnection: keep-alive\r\n\r\n{\"error\":\"Failed to convert value of type 'java.lang.String' to required type 'com.rootmusic.core.domain.RmidBackedObject'; nested exception is java.lang.NumberFormatException: A rmid needs to be of type Long. Recived 164527841654870016456\"}"
13
+ end
14
+
15
+ def self.service_unavailable
16
+ "HTTP/1.1 503 Service Unavailable\r\nDate: Wed, 06 Mar 2013 01:09:50 GMT\r\nServer: Apache-Coyote/1.1\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n"
17
+ end
18
+
19
+ def self.not_found
20
+ "HTTP/1.1 404 Not Found\r\nDate: Wed, 06 Mar 2013 01:09:50 GMT\r\nServer: Apache-Coyote/1.1\r\nContent-Length: 0\r\nConnection: keep-alive\r\n\r\n"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ require 'api_responses'
3
+
4
+ describe BandPage::Client do
5
+ let(:subject) {
6
+ BandPage::Client.new(config)
7
+ }
8
+
9
+ let(:config) {
10
+ BandPage::Config.new(
11
+ app_id: '1',
12
+ client_id: '2a',
13
+ secret_key: '3b',
14
+ band_id: '2'
15
+ )
16
+ }
17
+
18
+ before do
19
+ subject.token = BandPage::Token.new('sometoken', 5000)
20
+ end
21
+
22
+ describe 'connections' do
23
+ it 'creates a method for each connection which delegates to get' do
24
+ BandPage::Client::CONNECTIONS.each do |connection|
25
+ subject.should_receive(:get).with(connection)
26
+ subject.send(connection)
27
+ end
28
+ end
29
+ end
30
+
31
+ # This is a stand in for any of the connection methods
32
+ # they all behave the same
33
+ describe '.tracks' do
34
+ before do
35
+ FakeWeb.register_uri(:get, subject.send(:url, :tracks),
36
+ response: BandPage::RecordedApiResponses.tracks)
37
+ end
38
+ it 'returns tracks' do
39
+ subject.tracks.first.type.should == "Track"
40
+ end
41
+ end
42
+
43
+ context '401' do
44
+ before do
45
+ FakeWeb.register_uri(:get, subject.send(:url, :tracks),
46
+ body: "{'error':'invalid_token','error_description':'Invalid token signature'}",
47
+ status: ['401', 'UNAUTHORIZED'])
48
+ end
49
+
50
+ it 'raises an authorization error' do
51
+ expect {
52
+ subject.tracks
53
+ }.to raise_error(BandPage::AuthorizationError)
54
+ end
55
+ end
56
+
57
+ context '404' do
58
+ before do
59
+ FakeWeb.register_uri(:get, subject.send(:url, :tracks),
60
+ response: BandPage::RecordedApiResponses.not_found)
61
+ end
62
+
63
+ it 'raises a resource not found error' do
64
+ expect {
65
+ subject.tracks
66
+ }.to raise_error(BandPage::ResourceNotFoundError)
67
+ end
68
+ end
69
+
70
+ context '500' do
71
+ before do
72
+ FakeWeb.register_uri(:get, subject.send(:url, :tracks),
73
+ response: BandPage::RecordedApiResponses.server_error)
74
+ end
75
+
76
+ it 'raises a server error' do
77
+ expect {
78
+ subject.tracks
79
+ }.to raise_error(BandPage::ServerError)
80
+ end
81
+ end
82
+
83
+ context '503' do
84
+ before do
85
+ FakeWeb.register_uri(:get, subject.send(:url, :tracks),
86
+ response: BandPage::RecordedApiResponses.service_unavailable)
87
+ it 'reases a service unavailable error' do
88
+ expect {
89
+ subject.tracks
90
+ }.to raise_error(BandPage::ServiceUnavailableError)
91
+ end
92
+ end
93
+ end
94
+
95
+ end
96
+
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe BandPage::Token do
4
+ let(:subject) { BandPage::Token }
5
+
6
+ before do
7
+ @time = Time.now
8
+ Time.stub(:now).and_return(@time)
9
+ end
10
+
11
+ describe '.initialize' do
12
+ it 'sets expires_at' do
13
+ token = subject.new('tokenstring', '3600')
14
+ token.expires_at.should eq(@time + 3600)
15
+ end
16
+ end
17
+
18
+ describe '#expired' do
19
+ it 'is true if expires_at is a time in the past' do
20
+ token = subject.new('tokenstring', '-3600')
21
+ token.expired?.should be_true
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'band_page'
5
+ require 'fakeweb'
6
+
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ # This file was generated by the `rspec --init` command. Conventionally, all
10
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
11
+ # Require this file using `require "spec_helper"` to ensure that it is only
12
+ # loaded once.
13
+ #
14
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
15
+ RSpec.configure do |config|
16
+ config.treat_symbols_as_metadata_keys_with_true_values = true
17
+ config.run_all_when_everything_filtered = true
18
+ config.filter_run :focus
19
+
20
+ # Run specs in random order to surface order dependencies. If you find an
21
+ # order dependency and want to debug it, you can fix the order by providing
22
+ # the seed, which is printed after each run.
23
+ # --seed 1234
24
+ config.order = 'random'
25
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: band_page
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Brennan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
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: recursive-open-struct
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
+ - !ruby/object:Gem::Dependency
47
+ name: fakeweb
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Wrapper for BandPage API
63
+ email:
64
+ - james@carbonfive.com
65
+ - brennanmusic@gmail.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - bandpage.gemspec
77
+ - lib/band_page.rb
78
+ - lib/band_page/client.rb
79
+ - lib/band_page/config.rb
80
+ - lib/band_page/token.rb
81
+ - lib/band_page/version.rb
82
+ - spec/api_responses.rb
83
+ - spec/band_page/client_spec.rb
84
+ - spec/band_page/token_spec.rb
85
+ - spec/spec_helper.rb
86
+ homepage: https://github.com/jamesBrennan/bandpage_api
87
+ licenses: []
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 1.8.24
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: Wrapper for BandPage API - https://developers.bandpage.com/docs
110
+ test_files:
111
+ - spec/api_responses.rb
112
+ - spec/band_page/client_spec.rb
113
+ - spec/band_page/token_spec.rb
114
+ - spec/spec_helper.rb