marvelite 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +28 -12
- data/lib/marvelite.rb +0 -1
- data/lib/marvelite/api/client.rb +31 -12
- data/lib/marvelite/api/response.rb +12 -6
- data/lib/marvelite/version.rb +1 -1
- data/spec/marvelite/api/client_spec.rb +34 -8
- data/spec/spec_helper.rb +5 -1
- metadata +4 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a25275235911ff6c298db40d9a53cbdba48da58
|
4
|
+
data.tar.gz: 704f6f949a889ed333d996af13223fcda8a96b06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9057f0a8b511dced1d1865cca70270c80c86ac8befdad542e2592b8c5b37b0be845e318b7c43a5fbcf61f3a3e85a15e72baadff99905e991ec920ab470bc78f5
|
7
|
+
data.tar.gz: 265c411137e5af68cd206be287ba5c50bbf2874dec5a4703a2a6463f0259bc64021be5ea8e93e0bd8ba4c9771a9b308b1464b74ad1094f3ec68aff456cd137c9
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
### 0.1.0
|
4
|
+
* Adds Travis CI support.
|
5
|
+
* Support for Etags and Gzip compression. Infinite thanks to [Jon Allured](https://github.com/jonallured) for this contribution.
|
6
|
+
* Refactorings and cleanups, courtesy of [Jon Allured](https://github.com/jonallured)
|
7
|
+
|
3
8
|
### 0.0.9
|
4
9
|
* Adds the following endpoints (contributed by: [Patrick Hereford (@phereford)](https://github.com/phereford)):
|
5
10
|
* retrieve creators by connecting to the API's `/creators` endpoint
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# Marvelite
|
1
|
+
# Marvelite [![Build Status][travis-badge]][travis]
|
2
|
+
|
3
|
+
[travis-badge]: https://travis-ci.org/antillas21/marvelite.png
|
4
|
+
[travis]: http://travis-ci.org/antillas21/marvelite
|
2
5
|
|
3
6
|
Simple Ruby wrapper to communicate with the Marvel Comics API.
|
4
7
|
|
@@ -21,18 +24,16 @@ Or install it yourself as:
|
|
21
24
|
* [Usage](#usage)
|
22
25
|
* [Responses](#responses)
|
23
26
|
|
24
|
-
|
25
27
|
## Usage
|
26
28
|
|
27
|
-
Please register first in the [Marvel Comics Developer
|
29
|
+
Please register first in the [Marvel Comics Developer
|
30
|
+
Portal](http://developer.marvel.com/) to get your API credentials (a public key
|
31
|
+
and a private key, you'll need them both to configure and instantiate a client).
|
28
32
|
|
29
33
|
### Instantiate a client
|
30
34
|
|
31
35
|
```ruby
|
32
|
-
client = Marvelite::API::Client.new(
|
33
|
-
:public_key => 'abcd1234',
|
34
|
-
:private_key => '5678efgh'
|
35
|
-
)
|
36
|
+
client = Marvelite::API::Client.new( :public_key => 'abcd1234', :private_key => '5678efgh')
|
36
37
|
|
37
38
|
# fetch a list of characters
|
38
39
|
client.characters
|
@@ -104,12 +105,16 @@ client.story_comics(2210)
|
|
104
105
|
client.story_comics(2210, :format => 'graphic novel', :orderBy => 'title', :limit => 10)
|
105
106
|
```
|
106
107
|
|
107
|
-
See the list of [available
|
108
|
-
|
108
|
+
See the list of [available
|
109
|
+
methods](https://github.com/antillas21/marvelite/wiki/Documentation) in the
|
110
|
+
wiki.
|
109
111
|
|
110
112
|
## Responses
|
111
113
|
|
112
|
-
|
114
|
+
Most requests to the API, return a `Marvelite::API::Response` object if
|
115
|
+
successful or a `Marvelite::API::ErrorResponse` if API response returns an
|
116
|
+
error. These objects are nothing more than the raw API response enhanced with
|
117
|
+
Hashie methods.
|
113
118
|
|
114
119
|
This way you gain several adavantages to manipulate the response, like:
|
115
120
|
|
@@ -123,11 +128,22 @@ response.data
|
|
123
128
|
response.data[:results]
|
124
129
|
```
|
125
130
|
|
131
|
+
## Etags and Gzip support
|
132
|
+
|
133
|
+
Support for Etags is built into every endpoint:
|
126
134
|
|
135
|
+
```ruby
|
136
|
+
first_response = client.series
|
137
|
+
first_response.status # => 200
|
127
138
|
|
128
|
-
|
139
|
+
second_response = client.series headers: { 'If-None-Match' => first_response.etag }
|
140
|
+
second_response.status # => 304
|
141
|
+
```
|
129
142
|
|
130
|
-
|
143
|
+
```ruby
|
144
|
+
gzipped_response = client.series(:headers => {'Accept-Encoding' => 'gzip'})
|
145
|
+
#=> Faster response hash from Marvel's API series endpoint. :)
|
146
|
+
```
|
131
147
|
|
132
148
|
|
133
149
|
## Contributing
|
data/lib/marvelite.rb
CHANGED
data/lib/marvelite/api/client.rb
CHANGED
@@ -1,23 +1,29 @@
|
|
1
1
|
module Marvelite
|
2
2
|
module API
|
3
3
|
class Client
|
4
|
-
include ActiveModel::Model
|
5
4
|
include HTTParty
|
6
5
|
base_uri 'http://gateway.marvel.com'
|
7
6
|
|
8
7
|
attr_accessor :public_key, :private_key, :router, :api_version
|
9
8
|
|
10
|
-
|
11
|
-
validates_presence_of :private_key
|
9
|
+
class InvalidClientError < StandardError; end
|
12
10
|
|
13
11
|
def initialize(attrs)
|
14
|
-
|
12
|
+
check_for_errors(attrs)
|
13
|
+
@public_key = attrs.fetch(:public_key)
|
14
|
+
@private_key = attrs.fetch(:private_key)
|
15
15
|
@api_version = attrs.fetch(:api_version) { 'v1' }
|
16
16
|
@router = attrs.fetch(:router) { Marvelite.router(:api_version => @api_version) }
|
17
17
|
build_methods
|
18
18
|
end
|
19
19
|
|
20
20
|
private
|
21
|
+
def check_for_errors(attrs)
|
22
|
+
[:public_key, :private_key].each do |key|
|
23
|
+
raise InvalidClientError, "You need to provide a :#{key} param." unless attrs[key]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
21
27
|
def params(additional_params = {})
|
22
28
|
base_hash = { :apikey => public_key, :ts => ts, :hash => request_hash }
|
23
29
|
additional_params.merge(base_hash)
|
@@ -34,9 +40,11 @@ module Marvelite
|
|
34
40
|
end
|
35
41
|
|
36
42
|
def build_response_object(response)
|
37
|
-
case response
|
43
|
+
case response.code
|
38
44
|
when 200
|
39
45
|
Response.new(response)
|
46
|
+
when 304
|
47
|
+
NotModifiedResponse.new(response)
|
40
48
|
else
|
41
49
|
ErrorResponse.new(response)
|
42
50
|
end
|
@@ -49,6 +57,11 @@ module Marvelite
|
|
49
57
|
response
|
50
58
|
end
|
51
59
|
|
60
|
+
def pull_headers(options)
|
61
|
+
headers = options.delete(:headers) || {}
|
62
|
+
[options, headers]
|
63
|
+
end
|
64
|
+
|
52
65
|
def process_arguments(*args)
|
53
66
|
temp_id, temp_options = *args
|
54
67
|
if temp_id && temp_id.is_a?(Hash)
|
@@ -60,18 +73,24 @@ module Marvelite
|
|
60
73
|
else
|
61
74
|
options = {}
|
62
75
|
end
|
63
|
-
|
76
|
+
params, headers = pull_headers(options)
|
77
|
+
[{ id: id, options: params}, headers]
|
64
78
|
end
|
65
79
|
|
66
|
-
def fetch_response(route, params_hash = {})
|
80
|
+
def fetch_response(route, params_hash = {}, headers = {})
|
67
81
|
id = params_hash[:id]
|
68
82
|
options = params_hash[:options]
|
83
|
+
path = find_path(route, id)
|
84
|
+
|
85
|
+
self.class.get(path, query: params(options), headers: headers)
|
86
|
+
end
|
69
87
|
|
88
|
+
def find_path(route, id)
|
70
89
|
if id.nil?
|
71
|
-
|
90
|
+
router.send("#{route}_path".to_sym)
|
72
91
|
else
|
73
92
|
id = fetch_resource_id(route, id) if id.is_a?(String)
|
74
|
-
|
93
|
+
router.send("#{route}_path".to_sym, {:id => id})
|
75
94
|
end
|
76
95
|
end
|
77
96
|
|
@@ -86,8 +105,8 @@ module Marvelite
|
|
86
105
|
@router.routes.each do |_, hash|
|
87
106
|
name = hash[:name]
|
88
107
|
self.class.send(:define_method, name) do |*args|
|
89
|
-
params = process_arguments(*args)
|
90
|
-
response = fetch_response(name, params)
|
108
|
+
params, headers = process_arguments(*args)
|
109
|
+
response = fetch_response(name, params, headers)
|
91
110
|
build_response_object(response)
|
92
111
|
end
|
93
112
|
end
|
@@ -95,4 +114,4 @@ module Marvelite
|
|
95
114
|
|
96
115
|
end
|
97
116
|
end
|
98
|
-
end
|
117
|
+
end
|
@@ -7,11 +7,17 @@ module Marvelite
|
|
7
7
|
include Hashie::Extensions::IndifferentAccess
|
8
8
|
end
|
9
9
|
|
10
|
-
class ErrorResponse <
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
class ErrorResponse < Response; end
|
11
|
+
|
12
|
+
class NotModifiedResponse < Response
|
13
|
+
def initialize(response)
|
14
|
+
super({
|
15
|
+
status: 'Not Modified',
|
16
|
+
code: 304,
|
17
|
+
data: {},
|
18
|
+
etag: response.headers['etag']
|
19
|
+
})
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
17
|
-
end
|
23
|
+
end
|
data/lib/marvelite/version.rb
CHANGED
@@ -3,13 +3,15 @@ require 'spec_helper'
|
|
3
3
|
describe Marvelite::API::Client do
|
4
4
|
describe 'initialization' do
|
5
5
|
it 'requires a :public_key to be set' do
|
6
|
-
|
7
|
-
|
6
|
+
expect{ Marvelite::API::Client.new(:private_key => '12345') }.to raise_error(
|
7
|
+
Marvelite::API::Client::InvalidClientError, "You need to provide a :public_key param."
|
8
|
+
)
|
8
9
|
end
|
9
10
|
|
10
11
|
it 'requires a :private_key to be set' do
|
11
|
-
|
12
|
-
|
12
|
+
expect{ Marvelite::API::Client.new(:public_key => '1234') }.to raise_error(
|
13
|
+
Marvelite::API::Client::InvalidClientError, "You need to provide a :private_key param."
|
14
|
+
)
|
13
15
|
end
|
14
16
|
|
15
17
|
context 'valid' do
|
@@ -17,7 +19,9 @@ describe Marvelite::API::Client do
|
|
17
19
|
|
18
20
|
describe '#api_version' do
|
19
21
|
it 'receives an :api_version optional param' do
|
20
|
-
client = Marvelite::API::Client.new(
|
22
|
+
client = Marvelite::API::Client.new(
|
23
|
+
:public_key => '1234', :private_key => 'abcd', :api_version => 'v1'
|
24
|
+
)
|
21
25
|
expect(client.api_version).to eq('v1')
|
22
26
|
end
|
23
27
|
|
@@ -27,7 +31,7 @@ describe Marvelite::API::Client do
|
|
27
31
|
end
|
28
32
|
|
29
33
|
it 'is an instance of Marvelite::Client' do
|
30
|
-
expect
|
34
|
+
expect{ client }.to_not raise_error
|
31
35
|
expect(client).to be_a(Marvelite::API::Client)
|
32
36
|
end
|
33
37
|
|
@@ -38,6 +42,26 @@ describe Marvelite::API::Client do
|
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
45
|
+
describe 'etags' do
|
46
|
+
let(:client) { marvelite_test_client }
|
47
|
+
let(:etag) { '64aceb407b735957130fce343bf4933ed21a7cfc' }
|
48
|
+
|
49
|
+
before do
|
50
|
+
stub_304('series?apikey=123456&ts=1&hash=d4f1bab013916a533ef31e3ad5fb0887', etag)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns a NotModifiedResponse' do
|
54
|
+
headers = { 'If-None-Match' => "\"#{etag}\"" }
|
55
|
+
response = client.series(headers: headers)
|
56
|
+
|
57
|
+
expect(response).to be_a Marvelite::API::NotModifiedResponse
|
58
|
+
expect(response.code).to eq(304)
|
59
|
+
expect(response.status).to eq("Not Modified")
|
60
|
+
expect(response.etag).to eq(etag)
|
61
|
+
expect(response.data).to eq({})
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
41
65
|
context "private methods" do
|
42
66
|
describe '#ts' do
|
43
67
|
let(:client) { Marvelite::API::Client.new(:public_key => '1234', :private_key => 'abcd') }
|
@@ -57,8 +81,10 @@ describe Marvelite::API::Client do
|
|
57
81
|
|
58
82
|
it 'passes required API params to all requests' do
|
59
83
|
client.stub(:ts).and_return('1')
|
60
|
-
expect(client.send(:params)).to eq(
|
84
|
+
expect(client.send(:params)).to eq(
|
85
|
+
{:apikey => client.public_key, :ts => '1', :hash => 'ffd275c5130566a2916217b101f26150'}
|
86
|
+
)
|
61
87
|
end
|
62
88
|
end
|
63
89
|
end
|
64
|
-
end
|
90
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marvelite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antonio Antillon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.0.5
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: activemodel
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: bundler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
201
187
|
requirements:
|
202
188
|
- - '>='
|
203
189
|
- !ruby/object:Gem::Version
|
204
|
-
version:
|
190
|
+
version: 1.9.2
|
205
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
206
192
|
requirements:
|
207
193
|
- - '>='
|
@@ -209,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
195
|
version: '0'
|
210
196
|
requirements: []
|
211
197
|
rubyforge_project:
|
212
|
-
rubygems_version: 2.
|
198
|
+
rubygems_version: 2.1.11
|
213
199
|
signing_key:
|
214
200
|
specification_version: 4
|
215
201
|
summary: Simple wrapper around the Marvel Comics API
|