starwars 0.0.1 → 0.0.2
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/.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
@@ -0,0 +1,63 @@
|
|
1
|
+
module Starwars
|
2
|
+
# Custom error class for rescuing from all Starwars errors
|
3
|
+
class Error < StandardError
|
4
|
+
class << self
|
5
|
+
# Return a hash of error classes
|
6
|
+
# @return [Hash]
|
7
|
+
# @example get the total number of pages
|
8
|
+
# Starwars::Error.errors
|
9
|
+
# @api public
|
10
|
+
def errors
|
11
|
+
@errors ||= {
|
12
|
+
400 => Starwars::Error::BadRequest,
|
13
|
+
401 => Starwars::Error::Unauthorized,
|
14
|
+
403 => Starwars::Error::Forbidden,
|
15
|
+
404 => Starwars::Error::NotFound,
|
16
|
+
500 => Starwars::Error::InternalServerError,
|
17
|
+
503 => Starwars::Error::ServiceUnavailableError
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Initializes a new Error object
|
23
|
+
#
|
24
|
+
# @param message [Exception, String]
|
25
|
+
# @param _status [Exception, status]
|
26
|
+
# @return [Starwars::Error]
|
27
|
+
# @example
|
28
|
+
# Starwars::Error.new('I am your father', nil)
|
29
|
+
# @api public
|
30
|
+
def initialize(message = '', _status = nil)
|
31
|
+
super(message)
|
32
|
+
end
|
33
|
+
|
34
|
+
class ArgumentError < self; end
|
35
|
+
|
36
|
+
# Raised when Starwars returns a 4xx HTTP status status_code
|
37
|
+
class ClientError < self; end
|
38
|
+
|
39
|
+
# Raised when Starwars returns the HTTP status status_code 400
|
40
|
+
class BadRequest < ClientError; end
|
41
|
+
|
42
|
+
# Raised when Starwars returns the HTTP status status_code 401
|
43
|
+
class Unauthorized < ClientError; end
|
44
|
+
|
45
|
+
# Raised when Starwars returns the HTTP status status_code 403
|
46
|
+
class Forbidden < ClientError; end
|
47
|
+
|
48
|
+
# Raised when Starwars returns the HTTP status status_code 404
|
49
|
+
class NotFound < ClientError; end
|
50
|
+
|
51
|
+
# Raised when Starwars returns a 5xx HTTP status code
|
52
|
+
class ServerError < self; end
|
53
|
+
|
54
|
+
# Raised when Starwars returns the HTTP status status_code 500
|
55
|
+
class InternalServerError < ServerError; end
|
56
|
+
|
57
|
+
# Raised when Starwars returns the HTTP status status_code 503
|
58
|
+
class ServiceUnavailableError < ServerError; end
|
59
|
+
|
60
|
+
# Raised when the request times out
|
61
|
+
class RequestTimeout < self; end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
#
|
4
|
+
# ostruct for ruby 1.9 doesn't implement [] operater
|
5
|
+
# This a monkey patch my copying the ruby 2.0 version
|
6
|
+
class OpenStruct
|
7
|
+
#
|
8
|
+
# Fetch an object by id or URL
|
9
|
+
# @param [String] name
|
10
|
+
# @return [Object]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
def [](name)
|
14
|
+
@table[name.to_sym]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'starwars/error'
|
2
|
+
|
3
|
+
module Starwars
|
4
|
+
# Wrap request attrs
|
5
|
+
class Request
|
6
|
+
BASE_URL = 'http://swapi.co/api'
|
7
|
+
FORMAT = 'application/json'
|
8
|
+
|
9
|
+
# The format of the HTTP request
|
10
|
+
# @return [String]
|
11
|
+
# @api private
|
12
|
+
attr_accessor :as
|
13
|
+
|
14
|
+
# The http method for the request
|
15
|
+
# @return [Symbol]
|
16
|
+
# @api private
|
17
|
+
attr_accessor :method
|
18
|
+
|
19
|
+
# The resouce object that we going to call to fetch the data
|
20
|
+
# @return [Person, Film, Planet, Specie, Starship, Vehicle]
|
21
|
+
# @api private
|
22
|
+
attr_accessor :resource
|
23
|
+
|
24
|
+
# The remote url for the resource that we want to fetch
|
25
|
+
# @return [String]
|
26
|
+
# @api private
|
27
|
+
attr_accessor :uri
|
28
|
+
|
29
|
+
# Extra params we want to send with the http request
|
30
|
+
# @return [Hash]
|
31
|
+
# @api private
|
32
|
+
attr_accessor :params
|
33
|
+
|
34
|
+
# Initializer
|
35
|
+
# @param [Hash] attrs request attributes
|
36
|
+
# @option attrs [Starwars::] :resource
|
37
|
+
# @option attrs [Symbol] :method
|
38
|
+
# @option attrs [String] :uri
|
39
|
+
# @option attrs [Hash] :params
|
40
|
+
# @option attrs [String] :as
|
41
|
+
# @return [Starwars::Request]
|
42
|
+
# @example
|
43
|
+
# data = Request.new(resource: Person.new(id: 1), uri: "/something")
|
44
|
+
# @api public
|
45
|
+
def initialize(attrs)
|
46
|
+
self.resource = attrs.fetch(:resource)
|
47
|
+
self.method = attrs.fetch(:method) { :get }
|
48
|
+
self.uri = attrs.fetch(:uri)
|
49
|
+
self.as = attrs.fetch(:as) { FORMAT }
|
50
|
+
self.params = attrs.fetch(:params) { {} }
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Delegate to the Roar client to fetch data from api
|
55
|
+
# @return [Person, Film, Planet, Specie, Starship, Vehicle]
|
56
|
+
# @example
|
57
|
+
# request.perform_request
|
58
|
+
# @raise [Starwars::Error]
|
59
|
+
# @api public
|
60
|
+
def perform_request
|
61
|
+
resource.send(method, uri: uri, as: as)
|
62
|
+
|
63
|
+
rescue Roar::Transport::Error => e
|
64
|
+
raise_http_errors(e.response.code.to_i, e.response.msg)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
#
|
70
|
+
# Check the response code and raise exceptions if needed
|
71
|
+
# @param status [Integer]
|
72
|
+
# @param message [String]
|
73
|
+
# @return [void]
|
74
|
+
# @api private
|
75
|
+
def raise_http_errors(status, message)
|
76
|
+
error_class = Starwars::Error.errors[status]
|
77
|
+
fail(error_class.new(message, status)) if error_class
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Starwars
|
2
|
+
#
|
3
|
+
# A Film resource is an single film.
|
4
|
+
#
|
5
|
+
class Film < Starwars::Base
|
6
|
+
# Define the source name in the starwars api
|
7
|
+
RESOURCE_NAME = 'films'
|
8
|
+
|
9
|
+
# The title of this film
|
10
|
+
# @return [String]
|
11
|
+
# @example
|
12
|
+
# film.title #=> 'A New Hope'
|
13
|
+
# @api public
|
14
|
+
property :title
|
15
|
+
|
16
|
+
# The opening paragraphs at the beginning of this film
|
17
|
+
# @return [String]
|
18
|
+
# @example
|
19
|
+
# film.opening_crawl #=> 'It is a period of civil war ...'
|
20
|
+
# @api public
|
21
|
+
property :opening_crawl
|
22
|
+
|
23
|
+
# The name of the director of this film
|
24
|
+
# @return [String]
|
25
|
+
# @example
|
26
|
+
# film.director #=> 'George Lucas'
|
27
|
+
# @api public
|
28
|
+
property :director
|
29
|
+
|
30
|
+
# The name(s) of the producer(s) of this film. Comma seperated
|
31
|
+
# @return [String]
|
32
|
+
# @example
|
33
|
+
# film.producer #=> 'Gary Kurtz, Rick McCallum'
|
34
|
+
# @api public
|
35
|
+
property :producer
|
36
|
+
|
37
|
+
# The episode number of this film
|
38
|
+
# @return [Integer]
|
39
|
+
# @example
|
40
|
+
# film.episode_id #=> 1
|
41
|
+
# @api public
|
42
|
+
property :episode_id, type: Integer
|
43
|
+
|
44
|
+
# List of people
|
45
|
+
# @return [Array<Person>]
|
46
|
+
# @example
|
47
|
+
# film.characters
|
48
|
+
# @api public
|
49
|
+
collection :characters, class: Starwars::Person, deserialize: ->(_, fragment, _) { Person.new(url: fragment) }
|
50
|
+
|
51
|
+
# List of planets
|
52
|
+
# @return [Array<Person>]
|
53
|
+
# @example
|
54
|
+
# film.characters
|
55
|
+
# @api public
|
56
|
+
collection :planets, class: Starwars::Planet, deserialize: ->(_, fragment, _) { Planet.new(url: fragment) }
|
57
|
+
|
58
|
+
# List of starships
|
59
|
+
# @return [Array<Starship>]
|
60
|
+
# @example
|
61
|
+
# film.starships
|
62
|
+
# @api public
|
63
|
+
collection :starships, class: Starwars::Starship, deserialize: ->(_, fragment, _) { Starship.new(url: fragment) }
|
64
|
+
|
65
|
+
# List of vehicles
|
66
|
+
# @return [Array<Vehicle>]
|
67
|
+
# @example
|
68
|
+
# film.vehicles
|
69
|
+
# @api public
|
70
|
+
collection :vehicles, class: Starwars::Vehicle, deserialize: ->(_, fragment, _) { Vehicle.new(url: fragment) }
|
71
|
+
|
72
|
+
# List of species
|
73
|
+
# @return [Array<Specie>]
|
74
|
+
# @example
|
75
|
+
# film.species
|
76
|
+
# @api public
|
77
|
+
collection :species, class: Starwars::Specie, deserialize: ->(_, fragment, _) { Specie.new(url: fragment) }
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Starwars
|
2
|
+
#
|
3
|
+
# A Planet resource is a large mass, planet or planetoid in
|
4
|
+
# the Star Wars Universe, at the time of 0 ABY.
|
5
|
+
#
|
6
|
+
class Planets < Starwars::Cursor
|
7
|
+
collection :results, class: Starwars::Planet, deserialize: ->(_, fragment, _) { Planet.new(fragment) }
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Starwars
|
2
|
+
#
|
3
|
+
# A People resource is an individual person or character within the Star Wars universe.
|
4
|
+
#
|
5
|
+
class Person < Starwars::Base
|
6
|
+
#
|
7
|
+
# Define the source name in the starwars api
|
8
|
+
#
|
9
|
+
RESOURCE_NAME = 'people'
|
10
|
+
|
11
|
+
# The name of this person
|
12
|
+
# @return [String]
|
13
|
+
# @example
|
14
|
+
# person.name
|
15
|
+
# @api public
|
16
|
+
property :name
|
17
|
+
|
18
|
+
# The skin color of this person
|
19
|
+
# @return [String]
|
20
|
+
# @example
|
21
|
+
# person.skin_color
|
22
|
+
# @api public
|
23
|
+
property :skin_color
|
24
|
+
|
25
|
+
# The eye color of this person
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
#
|
29
|
+
# @note Will be "unknown" if not known or "n/a"
|
30
|
+
# if the person does not have an eye
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# person.eye_color
|
34
|
+
# @api public
|
35
|
+
property :eye_color
|
36
|
+
|
37
|
+
# The hair color of this person
|
38
|
+
#
|
39
|
+
# @return [String]
|
40
|
+
#
|
41
|
+
# @note: Will be "unknown" if not known or "n/a"
|
42
|
+
# if the person does not have hair
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# person.hair_color
|
46
|
+
# @api public
|
47
|
+
property :hair_color
|
48
|
+
|
49
|
+
# The birth year of the person
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
#
|
53
|
+
# @note using the in-universe standard of
|
54
|
+
# BBY or ABY - Before the Battle of Yavin or After the Battle of Yavin.
|
55
|
+
# The Battle of Yavin is a battle that occurs at the end of Star Wars
|
56
|
+
# episode IV: A New Hope
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# person.birth_year
|
60
|
+
# @api public
|
61
|
+
property :birth_year
|
62
|
+
|
63
|
+
# The gender of this person
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
#
|
67
|
+
# @note Either "Male", "Female" or "unknown", "n/a"
|
68
|
+
# if the person does not have a gender
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# person.gender
|
72
|
+
# @api public
|
73
|
+
property :gender
|
74
|
+
|
75
|
+
# The height of the person in centimeters
|
76
|
+
# @return [Integer]
|
77
|
+
# @example
|
78
|
+
# person.height
|
79
|
+
# @api public
|
80
|
+
property :height, type: Integer
|
81
|
+
|
82
|
+
# The mass of the person in kilograms
|
83
|
+
# @return [Integer]
|
84
|
+
# @example
|
85
|
+
# person.mass
|
86
|
+
# @api public
|
87
|
+
property :mass, type: Integer
|
88
|
+
|
89
|
+
# List of homeworlds
|
90
|
+
# @return [Array<Planet>]
|
91
|
+
# @example
|
92
|
+
# person.homeworlds
|
93
|
+
# @api public
|
94
|
+
property :homeworld, class: Starwars::Planet, deserialize: ->(_, fragment, _) { Planet.new(url: fragment) }
|
95
|
+
|
96
|
+
# List of films
|
97
|
+
# @return [Array<Film>]
|
98
|
+
# @example
|
99
|
+
# person.films
|
100
|
+
# @api public
|
101
|
+
collection :films, class: Starwars::Film, deserialize: ->(_, fragment, _) { Film.new(url: fragment) }
|
102
|
+
|
103
|
+
# List of species
|
104
|
+
# @return [Array<Specie>]
|
105
|
+
# @example
|
106
|
+
# person.species
|
107
|
+
# @api public
|
108
|
+
collection :species, class: Starwars::Specie, deserialize: ->(_, fragment, _) { Specie.new(url: fragment) }
|
109
|
+
|
110
|
+
# List of vehicles
|
111
|
+
# @return [Array<Vehicle>]
|
112
|
+
# @example
|
113
|
+
# person.vehicles
|
114
|
+
# @api public
|
115
|
+
collection :vehicles, class: Starwars::Vehicle, deserialize: ->(_, fragment, _) { Vehicle.new(url: fragment) }
|
116
|
+
|
117
|
+
# List of tarships
|
118
|
+
# @return [Array<Starship>]
|
119
|
+
# @example
|
120
|
+
# person.starships
|
121
|
+
# @api public
|
122
|
+
collection :starships, class: Starwars::Starship, deserialize: ->(_, fragment, _) { Starship.new(url: fragment) }
|
123
|
+
end
|
124
|
+
end
|
@@ -9,28 +9,15 @@ module Starwars
|
|
9
9
|
#
|
10
10
|
RESOURCE_NAME = 'planets'
|
11
11
|
|
12
|
-
include Starwars::Fetcher
|
13
|
-
|
14
|
-
# @return [String]
|
15
12
|
property :name
|
16
13
|
property :climate
|
17
14
|
property :gravity
|
18
15
|
property :terrain
|
19
|
-
property :url
|
20
|
-
|
21
|
-
# @return [Integer]
|
22
|
-
property :id, type: Integer
|
23
16
|
property :population, type: Integer
|
24
17
|
property :rotation_period, type: Integer
|
25
18
|
property :orbital_period, type: Integer
|
26
19
|
property :surface_water, type: Integer
|
27
20
|
property :diameter, type: Integer
|
28
|
-
|
29
|
-
# @return [Time]
|
30
|
-
property :created, type: Time
|
31
|
-
property :edited, type: Time
|
32
|
-
|
33
|
-
# @return [Array]
|
34
21
|
collection :residents, class: Starwars::Person, deserialize: ->(_, fragment, _) { Person.new(url: fragment) }
|
35
22
|
collection :films, class: Starwars::Film, deserialize: ->(_, fragment, _) { Film.new(url: fragment) }
|
36
23
|
end
|