marvelite 0.0.9 → 0.1.0
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.
- 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
|