luchadeer 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +29 -33
  5. data/lib/luchadeer.rb +0 -12
  6. data/lib/luchadeer/api.rb +42 -22
  7. data/lib/luchadeer/client.rb +2 -2
  8. data/lib/luchadeer/error.rb +4 -11
  9. data/lib/luchadeer/resource.rb +14 -2
  10. data/lib/luchadeer/resources.rb +135 -0
  11. data/lib/luchadeer/search.rb +1 -9
  12. data/lib/luchadeer/version.rb +1 -1
  13. data/spec/luchadeer/resources_spec.rb +6 -0
  14. data/spec/luchadeer_spec.rb +3 -6
  15. data/spec/spec_helper.rb +3 -0
  16. data/spec/support/shared_resource.rb +40 -0
  17. data/spec/support/shared_searchable.rb +65 -0
  18. metadata +11 -57
  19. data/lib/luchadeer/api/characters.rb +0 -11
  20. data/lib/luchadeer/api/companies.rb +0 -11
  21. data/lib/luchadeer/api/concepts.rb +0 -11
  22. data/lib/luchadeer/api/franchises.rb +0 -11
  23. data/lib/luchadeer/api/games.rb +0 -11
  24. data/lib/luchadeer/api/locations.rb +0 -11
  25. data/lib/luchadeer/api/objects.rb +0 -11
  26. data/lib/luchadeer/api/people.rb +0 -11
  27. data/lib/luchadeer/api/videos.rb +0 -11
  28. data/lib/luchadeer/character.rb +0 -13
  29. data/lib/luchadeer/company.rb +0 -13
  30. data/lib/luchadeer/concept.rb +0 -13
  31. data/lib/luchadeer/franchise.rb +0 -13
  32. data/lib/luchadeer/game.rb +0 -13
  33. data/lib/luchadeer/location.rb +0 -13
  34. data/lib/luchadeer/object.rb +0 -13
  35. data/lib/luchadeer/person.rb +0 -13
  36. data/lib/luchadeer/video.rb +0 -13
  37. data/spec/luchadeer/api/characters_spec.rb +0 -28
  38. data/spec/luchadeer/api/companies_spec.rb +0 -28
  39. data/spec/luchadeer/api/concepts_spec.rb +0 -28
  40. data/spec/luchadeer/api/franchises_spec.rb +0 -28
  41. data/spec/luchadeer/api/games_spec.rb +0 -28
  42. data/spec/luchadeer/api/locations_spec.rb +0 -28
  43. data/spec/luchadeer/api/objects_spec.rb +0 -28
  44. data/spec/luchadeer/api/people_spec.rb +0 -28
  45. data/spec/luchadeer/api/videos_spec.rb +0 -28
  46. data/spec/luchadeer/character_spec.rb +0 -27
  47. data/spec/luchadeer/company_spec.rb +0 -27
  48. data/spec/luchadeer/concept_spec.rb +0 -27
  49. data/spec/luchadeer/franchise_spec.rb +0 -27
  50. data/spec/luchadeer/game_spec.rb +0 -27
  51. data/spec/luchadeer/location_spec.rb +0 -27
  52. data/spec/luchadeer/object_spec.rb +0 -27
  53. data/spec/luchadeer/person_spec.rb +0 -27
  54. data/spec/luchadeer/video_spec.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bfbc3969949f80b2c6fe14722317f9b88cbdb31e
4
- data.tar.gz: f1ad8f45243b83a111039bbf6dc5263f6342edb2
3
+ metadata.gz: 1b94d3d201a337e35c0fbaf18442c990fcafd6f2
4
+ data.tar.gz: a95e9980249f97ff68359c88d5e9c186ecdef4b2
5
5
  SHA512:
6
- metadata.gz: 769594975368dc99024b093ae1027068e8d659c43833f6d4b8e47b702959e9dcd696bbd6a483251a3b13dae49b7fbf6367f5a1934f4cc50aa145b419ca381b63
7
- data.tar.gz: 8124aef0e0a7062d4d5ee373ab196d1a34f64381fb9cf748d228acbd432be0a816802987a08249c14cf7ebc475119131c14f6aea4020ff3ddcf288f84471edbf
6
+ metadata.gz: 7d362a2e26b74fe5fffd0f50053ea848a21257b12bc702e953a7bea2f473d9673b1310908a89f436a66d177578366fe398e9b1a474df544ea76d937a4661aa13
7
+ data.tar.gz: 2fdb677622f7c27dae3da5549b23e8e73035e845a983d0eb5af6b630304faceb80c4386fe1ea1c2aedd1c8db5e3a958536df0ba99d903804dea91d7b2f58d819
data/.travis.yml CHANGED
@@ -2,5 +2,7 @@ language: ruby
2
2
 
3
3
  rvm:
4
4
  - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
5
7
 
6
8
  script: bundle exec rspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- luchadeer (0.1.0)
4
+ luchadeer (0.2.0)
5
5
  faraday (~> 0.9.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -11,11 +11,14 @@
11
11
  The bombingest Giant Bomb API client library for Ruby.
12
12
 
13
13
  ## Features
14
- 1. Fully unit-tested.
14
+ 1. Supports all resources exposed by the Giant Bomb API. For a full list, see the [documentation][docs].
15
15
  2. Caches API responses.
16
- 3. fully.recursive.dot.syntax, no random hash[:syntax] cutoff point
17
- 4. Fetch full details for partial objects (e.g. embedded results) with object.detail.
18
- 5. Thread-ready (thready?): no global or class state. Use convenience methods to use a default client per-thread, or use an alternate syntax for full control.
16
+ 3. Fully unit-tested.
17
+ 4. fully.recursive.dot.syntax, no random hash[:syntax] cutoff point
18
+ 5. Fetch full details for partial objects (e.g. embedded results) with object.detail.
19
+ 6. Use convenience methods on a default client per-thread, or use an alternate syntax for full control of the client object.
20
+
21
+ [docs]: http://www.giantbomb.com/api/documentation
19
22
 
20
23
  ## Configuration
21
24
  Get your API key [here](http://www.giantbomb.com/api). If you have a premium account, your API key should give you access to subscriber-only video resources, as well as links to HD-quality videos.
@@ -23,50 +26,43 @@ Get your API key [here](http://www.giantbomb.com/api). If you have a premium acc
23
26
  ```ruby
24
27
  Luchadeer.configure(api_key: 'my_api_key') # default client for this thread
25
28
  Luchadeer::Client.new(api_key: 'my_api_key')
26
-
27
- # You can also pass a block to either method, and it will yield the client object to configure to your liking.
28
- Luchadeer.configure do |client|
29
- client.api_key = 'my_api_key'
30
- end
31
29
  ```
32
30
 
33
- ## Supported resources
34
- * game
35
- * franchise
36
- * character
37
- * concept
38
- * object
39
- * location
40
- * person
41
- * company
42
- * video
43
-
44
31
  ## Usage
45
32
 
46
33
  ```ruby
47
- # Resources
48
- Luchadeer::Game.find(21373) # or...
49
- my_client.game(21373) # => #<Luchadeer::Game name="Shin Megami Tensei: Persona 4" ...>
34
+ # Resources by name
35
+ # (you can omit the search query if you like)
36
+ Luchadeer::Game.search 'persona 4'
37
+ my_client.games 'persona 4'
38
+ Luchadeer::Video.search 'unprofessional'
39
+ my_client.videos 'unprofessional'
50
40
 
51
- # Search: mix and match whatever syntax you like
41
+ # Resources by ID
42
+ Luchadeer::Game.find 21373
43
+ my_client.game 21373
44
+ Luchadeer::RatingBoard.find 3
45
+ my_client.rating_board 3
46
+
47
+ # Custom searches
52
48
  Luchadeer::Search.new(page: 1, limit: 50, query: 'valkyria').fetch
53
49
 
54
50
  search = Luchadeer::Search.new
55
- search.page(1).limit(50).sort('name', :desc)
56
- search.resources([Luchadeer::Game, Luchadeer::Character])
57
- search.query('valkyria')
51
+ search.page(1).limit(50).sort('name', :desc) # default is :asc
52
+ search.resources [Luchadeer::Game, Luchadeer::Character] # strings work too
53
+ search.query 'valkyria'
58
54
  search.fetch
59
55
 
60
- Luchadeer::Search.new { |s|
56
+ search = Luchadeer::Search.new do |s|
61
57
  s.query = 'valkyria'
62
58
  s.page = 1
63
59
  s.limit = 50
64
- }.fetch
60
+ end
61
+
62
+ results = search.fetch
65
63
  ```
66
64
 
67
65
  ## TODO
68
66
  1. Add custom filtering to search (i.e., the 'filter' request parameter).
69
- 2. Add per-resource searching class methods on each resource object.
70
- 3. Refactor the test suite with shared example groups.
71
- 4. Make the caching layer more flexible - more options besides in-memory store. Add a null store, too.
72
- 5. Add remaining missing resources: accessory, chat, game_rating, genre, platform, promo, rating_board, region, release, review, theme, types, user_review, video_type. None of these show up in search. Refactoring is probably necessary.
67
+ 2. Make the caching layer more flexible - more options besides in-memory store. Add a null store, too.
68
+ 3. 'ghost' object pattern - lazy-load details for partial models when they're accessed, instead of requiring manual '.detail' invocation
data/lib/luchadeer.rb CHANGED
@@ -1,20 +1,8 @@
1
- require 'luchadeer/version'
2
-
3
1
  require 'luchadeer/api'
4
2
  require 'luchadeer/client'
5
3
  require 'luchadeer/error'
6
4
  require 'luchadeer/search'
7
5
 
8
- require 'luchadeer/character'
9
- require 'luchadeer/company'
10
- require 'luchadeer/concept'
11
- require 'luchadeer/franchise'
12
- require 'luchadeer/game'
13
- require 'luchadeer/location'
14
- require 'luchadeer/object'
15
- require 'luchadeer/person'
16
- require 'luchadeer/video'
17
-
18
6
  module Luchadeer
19
7
  class << self
20
8
  def configure(opts = {}, &blk)
data/lib/luchadeer/api.rb CHANGED
@@ -1,32 +1,47 @@
1
- require 'luchadeer/api/characters'
2
- require 'luchadeer/api/companies'
3
- require 'luchadeer/api/concepts'
4
- require 'luchadeer/api/franchises'
5
- require 'luchadeer/api/games'
6
- require 'luchadeer/api/locations'
7
- require 'luchadeer/api/objects'
8
- require 'luchadeer/api/people'
9
- require 'luchadeer/api/videos'
1
+ require 'luchadeer/resources'
10
2
 
11
3
  module Luchadeer
12
4
  module API
13
- API_MODULES = [
14
- Luchadeer::API::Characters,
15
- Luchadeer::API::Companies,
16
- Luchadeer::API::Concepts,
17
- Luchadeer::API::Franchises,
18
- Luchadeer::API::Games,
19
- Luchadeer::API::Locations,
20
- Luchadeer::API::Objects,
21
- Luchadeer::API::People,
22
- Luchadeer::API::Videos
5
+ attr_writer :cache
6
+
7
+ RESOURCES = [
8
+ Luchadeer::Accessory,
9
+ Luchadeer::Character,
10
+ Luchadeer::Chat,
11
+ Luchadeer::Company,
12
+ Luchadeer::Concept,
13
+ Luchadeer::Franchise,
14
+ Luchadeer::Game,
15
+ Luchadeer::GameRating,
16
+ Luchadeer::Genre,
17
+ Luchadeer::Location,
18
+ Luchadeer::Object,
19
+ Luchadeer::Person,
20
+ Luchadeer::Platform,
21
+ Luchadeer::Promo,
22
+ Luchadeer::RatingBoard,
23
+ Luchadeer::Region,
24
+ Luchadeer::Release,
25
+ Luchadeer::Review,
26
+ Luchadeer::Theme,
27
+ Luchadeer::UserReview,
28
+ Luchadeer::Video,
29
+ Luchadeer::VideoType
23
30
  ]
24
31
 
25
- API_MODULES.each do |mod|
26
- include mod
32
+ RESOURCES.each do |resource|
33
+ define_method resource::SINGULAR do |id, refresh = false|
34
+ fetch("#{resource::SINGULAR}/#{resource::RESOURCE_ID}-#{id}", refresh, resource)
35
+ end
36
+
37
+ define_method resource::PLURAL do |query = nil, refresh = false|
38
+ search_resource(resource::PLURAL, query, refresh, resource)
39
+ end
27
40
  end
28
41
 
29
- attr_writer :cache
42
+ def search(*args, &blk)
43
+ Luchadeer::Search.new(*args, &blk).fetch
44
+ end
30
45
 
31
46
  def cache(key, refresh = false, &blk)
32
47
  @cache ||= {}
@@ -47,5 +62,10 @@ module Luchadeer
47
62
  results.is_a?(Array) ? results.map { |r| klass.new(r) } : klass.new(results)
48
63
  end
49
64
 
65
+ def search_resource(endpoint, query, refresh = false, klass = Luchadeer::Resource)
66
+ query_string = "?filter=name:#{query}" unless query.nil? or query.length < 1
67
+ fetch("#{endpoint}#{query_string}", refresh, klass)
68
+ end
69
+
50
70
  end
51
71
  end
@@ -1,4 +1,5 @@
1
1
  require 'faraday'
2
+ require 'luchadeer/version'
2
3
  require 'luchadeer/middleware/follow_redirects'
3
4
  require 'luchadeer/middleware/parse_json'
4
5
  require 'luchadeer/middleware/parse_http_error'
@@ -45,8 +46,7 @@ module Luchadeer
45
46
  end
46
47
 
47
48
  def middleware
48
- Faraday::RackBuilder.new do |builder|
49
- # order is important
49
+ Faraday::RackBuilder.new do |builder| # order is important
50
50
  builder.response :parse_api_error
51
51
  builder.response :parse_json
52
52
  builder.response :parse_http_error
@@ -34,17 +34,10 @@ module Luchadeer
34
34
  }
35
35
  end
36
36
 
37
- private
38
-
39
- class RedirectLimitReached < Luchadeer::Error; end
40
- class RequestTimeout < Luchadeer::Error; end
37
+ %w[RedirectLimitReached RequestTimeout InvalidAPIKey URLFormatError FilterError
38
+ SubscriberOnly BadRequest NotFound InternalServerError ].each do |e|
39
+ const_set e, Class.new(Luchadeer::Error)
40
+ end
41
41
 
42
- class InvalidAPIKey < Luchadeer::Error; end
43
- class URLFormatError < Luchadeer::Error; end
44
- class FilterError < Luchadeer::Error; end
45
- class SubscriberOnly < Luchadeer::Error; end
46
- class BadRequest < Luchadeer::Error; end
47
- class NotFound < Luchadeer::Error; end
48
- class InternalServerError < Luchadeer::Error; end
49
42
  end
50
43
  end
@@ -1,5 +1,17 @@
1
+ require 'ostruct'
2
+
1
3
  module Luchadeer
2
- class Resource < OpenStruct
4
+ class Resource < ::OpenStruct
5
+
6
+ class << self
7
+ def find(id, refresh = false)
8
+ Luchadeer.client.send(self::SINGULAR, id, refresh)
9
+ end
10
+
11
+ def search(query = nil, refresh = false)
12
+ Luchadeer.client.send(self::PLURAL, query, refresh)
13
+ end
14
+ end
3
15
 
4
16
  # http://andreapavoni.com/blog/2013/4/create-recursive-openstruct-from-a-ruby-hash
5
17
  def initialize(hash = nil)
@@ -27,7 +39,7 @@ module Luchadeer
27
39
 
28
40
  def deep_structify(k, v)
29
41
  case v
30
- when Hash then Luchadeer::Resource.new(v)
42
+ when Hash then Luchadeer::Resource.new(v)
31
43
  when Array then v.map { |n| Luchadeer::Resource.new(n) }
32
44
  else v
33
45
  end
@@ -0,0 +1,135 @@
1
+ require 'luchadeer/resource'
2
+
3
+ module Luchadeer
4
+ class Accessory < Resource
5
+ SINGULAR = :accessory
6
+ PLURAL = :accessories
7
+ RESOURCE_ID = 3000
8
+ end
9
+
10
+ class Character < Resource
11
+ SINGULAR = :character
12
+ PLURAL = :characters
13
+ RESOURCE_ID = 3005
14
+ end
15
+
16
+ class Chat < Resource
17
+ SINGULAR = :chat
18
+ PLURAL = :chats
19
+ RESOURCE_ID = 2450
20
+ end
21
+
22
+ class Company < Resource
23
+ SINGULAR = :company
24
+ PLURAL = :companies
25
+ RESOURCE_ID = 3010
26
+ end
27
+
28
+ class Concept < Resource
29
+ SINGULAR = :concept
30
+ PLURAL = :concepts
31
+ RESOURCE_ID = 3015
32
+ end
33
+
34
+ class Franchise < Resource
35
+ SINGULAR = :franchise
36
+ PLURAL = :franchises
37
+ RESOURCE_ID = 3025
38
+ end
39
+
40
+ class Game < Resource
41
+ SINGULAR = :game
42
+ PLURAL = :games
43
+ RESOURCE_ID = 3030
44
+ end
45
+
46
+ class GameRating < Resource
47
+ SINGULAR = :game_rating
48
+ PLURAL = :game_ratings
49
+ RESOURCE_ID = 3065
50
+ end
51
+
52
+ class Genre < Resource
53
+ SINGULAR = :genre
54
+ PLURAL = :genres
55
+ RESOURCE_ID = 3060
56
+ end
57
+
58
+ class Location < Resource
59
+ SINGULAR = :location
60
+ PLURAL = :locations
61
+ RESOURCE_ID = 3035
62
+ end
63
+
64
+ class Object < Resource
65
+ SINGULAR = :object
66
+ PLURAL = :objects
67
+ RESOURCE_ID = 3055
68
+ end
69
+
70
+ class Person < Resource
71
+ SINGULAR = :person
72
+ PLURAL = :people
73
+ RESOURCE_ID = 3040
74
+ end
75
+
76
+ class Platform < Resource
77
+ SINGULAR = :platform
78
+ PLURAL = :platforms
79
+ RESOURCE_ID = 3045
80
+ end
81
+
82
+ class Promo < Resource
83
+ SINGULAR = :promo
84
+ PLURAL = :promos
85
+ RESOURCE_ID = 1700
86
+ end
87
+
88
+ class RatingBoard < Resource
89
+ SINGULAR = :rating_board
90
+ PLURAL = :rating_boards
91
+ RESOURCE_ID = 3070
92
+ end
93
+
94
+ class Region < Resource
95
+ SINGULAR = :region
96
+ PLURAL = :regions
97
+ RESOURCE_ID = 3075
98
+ end
99
+
100
+ class Release < Resource
101
+ SINGULAR = :release
102
+ PLURAL = :releases
103
+ RESOURCE_ID = 3050
104
+ end
105
+
106
+ class Review < Resource
107
+ SINGULAR = :review
108
+ PLURAL = :reviews
109
+ RESOURCE_ID = 1900
110
+ end
111
+
112
+ class Theme < Resource
113
+ SINGULAR = :theme
114
+ PLURAL = :themes
115
+ RESOURCE_ID = 3032
116
+ end
117
+
118
+ class UserReview < Resource
119
+ SINGULAR = :user_review
120
+ PLURAL = :user_reviews
121
+ RESOURCE_ID = 2200
122
+ end
123
+
124
+ class Video < Resource
125
+ SINGULAR = :video
126
+ PLURAL = :videos
127
+ RESOURCE_ID = 2300
128
+ end
129
+
130
+ class VideoType < Resource
131
+ SINGULAR = :video_type
132
+ PLURAL = :video_types
133
+ RESOURCE_ID = 2320
134
+ end
135
+ end
@@ -1,12 +1,4 @@
1
- require 'luchadeer/character'
2
- require 'luchadeer/company'
3
- require 'luchadeer/concept'
4
- require 'luchadeer/franchise'
5
- require 'luchadeer/game'
6
- require 'luchadeer/location'
7
- require 'luchadeer/object'
8
- require 'luchadeer/person'
9
- require 'luchadeer/video'
1
+ require 'luchadeer/resources'
10
2
 
11
3
  module Luchadeer
12
4
  class Search
@@ -1,3 +1,3 @@
1
1
  module Luchadeer
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end