starwars 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +1 -0
- data/README.md +63 -19
- data/lib/starwars.rb +16 -7
- data/lib/starwars/base.rb +129 -25
- data/lib/starwars/cursor.rb +110 -0
- data/lib/starwars/error.rb +63 -0
- data/lib/starwars/overrides/ostruct.rb +16 -0
- data/lib/starwars/request.rb +80 -0
- data/lib/starwars/resources/film.rb +79 -0
- data/lib/starwars/resources/paginated/films.rb +8 -0
- data/lib/starwars/resources/paginated/people.rb +8 -0
- data/lib/starwars/resources/paginated/planets.rb +9 -0
- data/lib/starwars/resources/paginated/species.rb +8 -0
- data/lib/starwars/resources/paginated/starships.rb +8 -0
- data/lib/starwars/resources/paginated/vehicles.rb +8 -0
- data/lib/starwars/resources/person.rb +124 -0
- data/lib/starwars/{planet.rb → resources/planet.rb} +0 -13
- data/lib/starwars/{specie.rb → resources/specie.rb} +1 -15
- data/lib/starwars/resources/starship.rb +115 -0
- data/lib/starwars/resources/vehicle.rb +106 -0
- data/lib/starwars/version.rb +1 -1
- data/spec/fixtures/404.json +1 -0
- data/spec/fixtures/planets_page1.json +1 -0
- data/spec/fixtures/planets_page2.json +1 -0
- data/spec/starwars/base_spec.rb +17 -0
- data/spec/starwars/cursor_spec.rb +76 -0
- data/spec/starwars/person_spec.rb +1 -1
- data/spec/starwars/request_spec.rb +29 -0
- data/spec/starwars/resources/paginated/planets_spec.rb +38 -0
- data/starwars.gemspec +0 -1
- metadata +32 -23
- data/lib/starwars/fetcher.rb +0 -40
- data/lib/starwars/film.rb +0 -35
- data/lib/starwars/person.rb +0 -39
- data/lib/starwars/starship.rb +0 -40
- data/lib/starwars/vehicle.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3c2a3fcfdfe161e04b8f4e5680513ce45fb5ed
|
4
|
+
data.tar.gz: 2c0a63b841991f163d15156d2f42ec1644eb7320
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 438b2c0f53551ed7bf5ee790bbe2bd052282f5838636ff4e4b1ec9c47c167f9ca9db11bfbddb9291eb520b7383bf52e4ea8f6a93ea0fa9be35a9a017199c15b6
|
7
|
+
data.tar.gz: 6638b91db1386184b23ed1f29d9841f3d2f177738126d289c496028560bdd6714ea70f7c4d5775e9c7a1adf9a0b5d8f0736970e2ab89512cb7256bdfb3dd1d50
|
data/.rubocop.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
Metrics/LineLength:
|
2
|
-
Max:
|
2
|
+
Max: 160
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Starwars
|
2
2
|
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/moski/starwars/badge.png?branch=master)](https://coveralls.io/r/moski/starwars?branch=master)
|
4
|
+
[![Build Status](https://travis-ci.org/moski/starwars.svg?branch=master)](https://travis-ci.org/moski/starwars)
|
5
|
+
[![Inline docs](http://inch-ci.org/github/moski/starwars.svg?branch=master&style=flat)](http://inch-ci.org/github/moski/starwars)
|
6
|
+
|
3
7
|
A Ruby interface for http://swapi.co/ - the Star Wars API
|
4
8
|
![Starwars](https://s3.amazonaws.com/f.cl.ly/items/1r2F2K460v1R2o011n1M/star-wars-evolution-evolution-funny.jpg)
|
5
9
|
|
@@ -26,29 +30,69 @@ Or install it yourself as:
|
|
26
30
|
|
27
31
|
$ gem install starwars
|
28
32
|
|
33
|
+
|
34
|
+
## Available Resources
|
35
|
+
|
36
|
+
* `Starwars::Person` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/person.rb))
|
37
|
+
* `Starwars::Film` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/film.rb))
|
38
|
+
* `Starwars::Planet` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/planet.rb))
|
39
|
+
* `Starwars::Specie` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/specie.rb))
|
40
|
+
* `Starwars::Starship` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/starship.rb))
|
41
|
+
* `Starwars::Vehicle` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/vehicle.rb))
|
42
|
+
|
29
43
|
## Usage
|
30
|
-
require "starwars"
|
31
|
-
luke = Starwars::Person.fetch(1)
|
32
|
-
puts luke.name
|
33
|
-
puts luke.height
|
34
44
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
45
|
+
All the resources defined above have 2 functions, `#fetch` and `#fetch_all`
|
46
|
+
|
47
|
+
## #Fetch
|
48
|
+
|
49
|
+
`#fetch` is used to fetch a single resource via ID or Resource URL
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
Starwars::Person.fetch(1).name
|
53
|
+
Starwars::Person.fetch('http://swapi.co/api/people/3/').name
|
54
|
+
```
|
55
|
+
|
56
|
+
## #fetch_all
|
57
|
+
|
58
|
+
`#fetch_all` is used to fetch all resources via pagination
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
planets = Starwars::Planet.fetch_all
|
62
|
+
|
63
|
+
# to access the items use #items
|
64
|
+
planets.items.map(&:name)
|
65
|
+
planets.items.each{|item| p item.inspect}
|
66
|
+
|
67
|
+
# you can also use #results instead of iteams
|
68
|
+
planets.results.map(&:name)
|
69
|
+
```
|
70
|
+
|
71
|
+
## Pagination
|
72
|
+
|
73
|
+
using `#fetch_all` will yield a pagination response:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
starships = Starwars::Starship.fetch_all
|
77
|
+
p starships.number_of_pages
|
78
|
+
p starships.last_page?
|
79
|
+
p starships.next_page?
|
80
|
+
```
|
81
|
+
|
82
|
+
To iterate pages you can use the following interface:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Starwars::Starship.fetch_all.each{|page|
|
86
|
+
p page.next
|
87
|
+
p page.previous
|
88
|
+
p page.results.size
|
89
|
+
}
|
90
|
+
```
|
39
91
|
|
40
|
-
|
41
|
-
|
42
|
-
falcon.pilots.each do |piolt|
|
43
|
-
puts piolt.fetch.name
|
44
|
-
end
|
92
|
+
## Documentation
|
45
93
|
|
46
|
-
|
94
|
+
the gem is fairly documented. Browse the YARD [documentaion](http://rubydoc.info/gems/starwars/) for more information.
|
47
95
|
|
48
|
-
aldeeran = Starwars::Planet.new(url: 'http://swapi.co/api/planets/3/').fetch
|
49
|
-
puts aldeeran.name
|
50
|
-
puts aldeeran.residents
|
51
|
-
puts aldeeran.population
|
52
96
|
|
53
97
|
## Contributing
|
54
98
|
|
@@ -56,4 +100,4 @@ Or install it yourself as:
|
|
56
100
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
57
101
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
58
102
|
4. Push to the branch (`git push origin my-new-feature`)
|
59
|
-
5. Create a new Pull Request
|
103
|
+
5. Create a new Pull Request
|
data/lib/starwars.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'starwars/version'
|
2
2
|
require 'starwars/base'
|
3
|
-
require 'starwars/
|
3
|
+
require 'starwars/request'
|
4
|
+
require 'starwars/cursor'
|
4
5
|
|
5
6
|
# Avoid circuler require issues :(
|
6
7
|
module Starwars
|
@@ -11,9 +12,17 @@ module Starwars
|
|
11
12
|
class Vehicle < Starwars::Base; end
|
12
13
|
class Starship < Starwars::Base; end
|
13
14
|
end
|
14
|
-
require 'starwars/planet'
|
15
|
-
require 'starwars/person'
|
16
|
-
require 'starwars/specie'
|
17
|
-
require 'starwars/vehicle'
|
18
|
-
require 'starwars/starship'
|
19
|
-
require 'starwars/film'
|
15
|
+
require 'starwars/resources/planet'
|
16
|
+
require 'starwars/resources/person'
|
17
|
+
require 'starwars/resources/specie'
|
18
|
+
require 'starwars/resources/vehicle'
|
19
|
+
require 'starwars/resources/starship'
|
20
|
+
require 'starwars/resources/film'
|
21
|
+
|
22
|
+
# Resources with pagination
|
23
|
+
require 'starwars/resources/paginated/planets'
|
24
|
+
require 'starwars/resources/paginated/films'
|
25
|
+
require 'starwars/resources/paginated/people'
|
26
|
+
require 'starwars/resources/paginated/species'
|
27
|
+
require 'starwars/resources/paginated/starships'
|
28
|
+
require 'starwars/resources/paginated/vehicles'
|
data/lib/starwars/base.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'roar/json'
|
2
2
|
require 'roar/client'
|
3
3
|
require 'roar/coercion'
|
4
|
-
require 'ostruct'
|
5
|
-
require 'equalizer'
|
4
|
+
require 'starwars/overrides/ostruct'
|
6
5
|
require 'virtus'
|
7
6
|
|
8
7
|
module Starwars
|
@@ -10,6 +9,10 @@ module Starwars
|
|
10
9
|
# Base Class for fetching all the data from the remote api.
|
11
10
|
# All Classes should inhert from this class.
|
12
11
|
#
|
12
|
+
# Abstract base class for the different resources.
|
13
|
+
# Provides some helper methods for the resources.
|
14
|
+
#
|
15
|
+
# @abstract
|
13
16
|
class Base < OpenStruct
|
14
17
|
include Roar::JSON
|
15
18
|
include Roar::Client
|
@@ -18,36 +21,137 @@ module Starwars
|
|
18
21
|
BASE_URL = 'http://swapi.co/api'
|
19
22
|
FORMAT = 'application/json'
|
20
23
|
|
24
|
+
#
|
25
|
+
# Class level methods for resources to fetch data from api
|
26
|
+
# @abstract
|
27
|
+
class << self
|
28
|
+
#
|
29
|
+
# Fetch an object by id or URL
|
30
|
+
# @param [String, Integer] param String for full resouce url or the resouce id
|
31
|
+
# @return [Person, Film, Planet, Specie, Starship, Vehicle]
|
32
|
+
# @example Fetch person by id
|
33
|
+
# Starwars::Person.fetch(1)
|
34
|
+
#
|
35
|
+
# @example Fetch person by url
|
36
|
+
# Starwars::Person.fetch("http://swapi.co/api/people/2/")
|
37
|
+
# @api public
|
38
|
+
def fetch(param)
|
39
|
+
object = new(url: link(param))
|
40
|
+
Starwars::Request.new(object.request_attributes).perform_request
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Fetch all resource data page by page
|
45
|
+
# @return [People, Films, Planets, Species, Starships, Vehicles]
|
46
|
+
# @example Fetch Planets page by page
|
47
|
+
# Starwars::Planet.fetch_all.each do |page|
|
48
|
+
# puts page.items.size
|
49
|
+
# end
|
50
|
+
# @api public
|
51
|
+
def fetch_all
|
52
|
+
klass_name = Starwars.const_get(name.split('::').last).const_get('RESOURCE_NAME')
|
53
|
+
object = Starwars.const_get("#{klass_name.capitalize}").new(url: "#{Starwars::Base::BASE_URL}/#{klass_name}/")
|
54
|
+
Starwars::Request.new(resource: object, uri: object.url, params: {}).perform_request
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
#
|
60
|
+
# Generate a resource link based on the passed params
|
61
|
+
# @param [String, Integer] param String for full resouce url or the resouce id
|
62
|
+
# @return [String] resouce link
|
63
|
+
# @api private
|
64
|
+
def link(param)
|
65
|
+
if param.is_a? String
|
66
|
+
param
|
67
|
+
else
|
68
|
+
"#{Starwars::Base::BASE_URL}/#{const_get('RESOURCE_NAME')}/#{param}/"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# The time the resource was created
|
74
|
+
# @return [Time]
|
75
|
+
# @example
|
76
|
+
# film.created
|
77
|
+
# @api public
|
78
|
+
property :created, type: Time
|
79
|
+
|
80
|
+
# The time the resource was edited
|
81
|
+
# @return [Time]
|
82
|
+
# @example
|
83
|
+
# film.edited
|
84
|
+
# @api public
|
85
|
+
property :edited, type: Time
|
86
|
+
|
87
|
+
# The resource unique id
|
88
|
+
# @return [Integer]
|
89
|
+
# @example
|
90
|
+
# film.id #=> 1
|
91
|
+
# @api public
|
92
|
+
property :id, type: Integer
|
93
|
+
|
94
|
+
# The hypermedia URL of this resource
|
95
|
+
# @return [String]
|
96
|
+
# @example
|
97
|
+
# film.url #=> 'http://swapi.co/api/films/1/'
|
98
|
+
# @api public
|
99
|
+
property :url
|
100
|
+
|
101
|
+
#
|
102
|
+
# Overide the == method for any resource to check the ID and URL
|
103
|
+
# @param [People, Films, Planets, Species, Starships, Vehicles] other
|
104
|
+
# @return [Boolean]
|
105
|
+
# @example If id's and urls are equal
|
106
|
+
# Starwars::Planet.new(id: 1, url: "/some") == Starwars::Planet.new(id: 1, url: "/some") #=> true
|
107
|
+
# @example If id's and urls are equal
|
108
|
+
# Starwars::Planet.new(id: 2, url: "/some") == Starwars::Planet.new(id: 1, url: "/some") #=> false
|
109
|
+
# @example If id's and urls are equal
|
110
|
+
# Starwars::Planet.new(id: 1, url: "/some1") == Starwars::Planet.new(id: 1, url: "/some") #=> false
|
111
|
+
# @api public
|
21
112
|
def ==(other)
|
22
113
|
id == other.id && url == other.url
|
23
114
|
end
|
24
115
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
116
|
+
#
|
117
|
+
# Fetch a resource if the ID or URL is set
|
118
|
+
# @return [Person, Film, Planet, Specie, Starship, Vehicle]
|
119
|
+
# @example Fetch person by id
|
120
|
+
# Starwars::Person.new(id: 1).fetch
|
121
|
+
#
|
122
|
+
# @example Fetch person by url
|
123
|
+
# Starwars::Person.new(url: "http://swapi.co/api/people/2/").fetch
|
124
|
+
# @api public
|
125
|
+
def fetch
|
126
|
+
Starwars::Request.new(request_attributes).perform_request
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Generate the Request initialize params
|
131
|
+
# @param [Hash] opts the options to create a Request with.
|
132
|
+
# @option opts [Person, Film, Planet, Specie, Starship, Vehicle] :resource
|
133
|
+
# @option opts [String] :uri resource uri
|
134
|
+
# @option opts [Hash] :params other params
|
135
|
+
# @return [Hash]
|
136
|
+
# @api private
|
137
|
+
def request_attributes(opts = {})
|
138
|
+
{ resource: self, uri: link, params: {} }.merge(opts)
|
139
|
+
end
|
140
|
+
|
141
|
+
protected
|
142
|
+
|
143
|
+
#
|
144
|
+
# Generate a resource link from the URL or id
|
145
|
+
# @return [String] resource link
|
146
|
+
# @raise [Starwars::Error::ArgumentError] if no id or url
|
147
|
+
# @api private
|
148
|
+
def link
|
29
149
|
if url
|
30
|
-
|
31
|
-
#
|
32
|
-
# Try to fetch using the resource name and ID
|
33
|
-
#
|
150
|
+
url
|
34
151
|
elsif id
|
35
|
-
|
152
|
+
"#{Starwars::Base::BASE_URL}/#{self.class::RESOURCE_NAME}/#{id}/"
|
36
153
|
else
|
37
|
-
fail '
|
38
|
-
end
|
39
|
-
end
|
40
|
-
class << self
|
41
|
-
def fetch(resources, id)
|
42
|
-
#
|
43
|
-
# Special case for person and people, instead of removing the s
|
44
|
-
#
|
45
|
-
if (resources == 'people')
|
46
|
-
resources = 'person'
|
47
|
-
else
|
48
|
-
resources.slice!(-1, 1)
|
49
|
-
end
|
50
|
-
Starwars.const_get(resources.capitalize).new(id: id).fetch
|
154
|
+
fail(Starwars::Error::ArgumentError.new('Please use id or url to fetch resouce', nil))
|
51
155
|
end
|
52
156
|
end
|
53
157
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Starwars
|
2
|
+
#
|
3
|
+
# A pagination container for starwars
|
4
|
+
#
|
5
|
+
class Cursor < Starwars::Base
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
#
|
9
|
+
# including Enumerable adds a "count" method to the class
|
10
|
+
# and for some reason:
|
11
|
+
# property :count, as: number_of_pages
|
12
|
+
# is not working, i am not sure it's a roar thing or from the representable gem.
|
13
|
+
# As a workaround, lets create "number_of_pages" method that returns
|
14
|
+
# the count property
|
15
|
+
# @todo - check why as: is not working
|
16
|
+
property :count
|
17
|
+
|
18
|
+
#
|
19
|
+
# Next holds the URL for the next page. If there is no next page, next
|
20
|
+
# should be set to nil
|
21
|
+
property :next
|
22
|
+
|
23
|
+
#
|
24
|
+
# Previous holds the URL for the previous page. If there is no previous
|
25
|
+
# page previous should be set to nil
|
26
|
+
property :previous
|
27
|
+
|
28
|
+
# Results contains the results within the page.
|
29
|
+
#
|
30
|
+
collection :results
|
31
|
+
|
32
|
+
# A wrapper to get the pages count from the api
|
33
|
+
# @return [Integer]
|
34
|
+
# @example get the total number of pages
|
35
|
+
# Starwars::Planet.fetch_all.number_of_pages
|
36
|
+
# @example get the total number of pages
|
37
|
+
# Starwars::Starship.fetch_all.number_of_pages
|
38
|
+
# @api public
|
39
|
+
def number_of_pages
|
40
|
+
self[:count]
|
41
|
+
end
|
42
|
+
|
43
|
+
# A wrapper to get the results within a page
|
44
|
+
# @note This wrapper is needed to define the items alias method
|
45
|
+
# @return [Array]
|
46
|
+
# @example Return the items array within the page
|
47
|
+
# Starwars::Planet.fetch_all.results
|
48
|
+
# Starwars::Planet.fetch_all.items
|
49
|
+
# @api public
|
50
|
+
def results
|
51
|
+
self[:results]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Checks wheather this is the last page
|
55
|
+
# @return [Boolean]
|
56
|
+
# @example are we at the last page?
|
57
|
+
# Starwars::Planet.fetch_all.last_page?
|
58
|
+
# @api public
|
59
|
+
def last_page?
|
60
|
+
!next_page?
|
61
|
+
end
|
62
|
+
|
63
|
+
# Checks wheather this there is more pages
|
64
|
+
# @return [Boolean]
|
65
|
+
# @example do we have a next page?
|
66
|
+
# Starwars::Planet.fetch_all.next_page?
|
67
|
+
# @api public
|
68
|
+
def next_page?
|
69
|
+
!self.next.nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the next page
|
73
|
+
# @return [Starwars::Base]
|
74
|
+
# @example fetch the next page
|
75
|
+
# page = Starwars::Planet.fetch_all
|
76
|
+
# page.next_page
|
77
|
+
# @api public
|
78
|
+
def next_page
|
79
|
+
return if last_page?
|
80
|
+
perform_request
|
81
|
+
end
|
82
|
+
|
83
|
+
# Yields the subsequent page responses to a given block
|
84
|
+
# @yieldparam [Starwars::Base] response
|
85
|
+
# @return [Enumerable, nil]
|
86
|
+
# @example fetch the next page
|
87
|
+
# Starwars::Planet.fetch_all.each_page{|page| p page.items.map(&:name)}
|
88
|
+
# Starwars::Planet.fetch_all.each{|page| p page.items.map(&:name)}
|
89
|
+
# Starwars::Planet.fetch_all.each_with_index{|page, index|
|
90
|
+
# p page.items.map(&:name)
|
91
|
+
# }
|
92
|
+
# @api public
|
93
|
+
def each_page
|
94
|
+
return to_enum(__callee__) unless block_given?
|
95
|
+
yield(next_page) until last_page?
|
96
|
+
end
|
97
|
+
|
98
|
+
alias_method :each, :each_page
|
99
|
+
alias_method :items, :results
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# Delegate to the request class to perform fetch data from remote server
|
104
|
+
# @return [People, Films, Planets, Species, Starships, Vehicles]
|
105
|
+
# @api private
|
106
|
+
def perform_request
|
107
|
+
Request.new(request_attributes(uri: self.next)).perform_request
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|