luchadeer 0.2.0 → 0.3.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.
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