hunting_season 0.0.4 → 0.0.5

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MjBhM2U0NmJlYjNmM2FiNDUxY2U4M2FmZGRiZTZlYTQyNjkxM2NiMg==
5
- data.tar.gz: !binary |-
6
- ZTEyYzI5ZTlhMTcxMmZhZjcwZTdhMTA5MjNlNDQ0M2VlZWE2ZjhhYQ==
2
+ SHA1:
3
+ metadata.gz: d5b4c9215d09f4fc84654338062e0b28c3e6147b
4
+ data.tar.gz: 8f0e9c7c28d45278e28ad041bff6f43ead27e953
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MzA0ODZiMDZhOTBhNDgwNWI3NzBhMTUxYzcyOTkzYzU5MmQ4MGYwNTgxNWE1
10
- ZTAyZWVmZjJjMDBmZjdjZjJmYTgzMTMwMWVlNDBkMzUwNTExMGEzMDQ0MDY5
11
- MGM1NGY5OWIyYTA1YTVmMTU4MDc5MjkxZDZmOTI2ZmMwYjY4MGE=
12
- data.tar.gz: !binary |-
13
- Y2EzYzQ4MTlhMjAwYzgzN2YwMWJmN2Q5ZmU5Mzk0Zjc2ODM4MWEwZWRjZWM3
14
- MTFhOTVkOTRiN2RmNDk2ZTJiNTFiOWFiYTJlMzIyMmFlNDYwYWFlMzRjYTQw
15
- ZWI5ZWE4NGM3NDY4NTRhODEwMTcwNTZkZTAwNDNlMWMzMWY1ZjY=
6
+ metadata.gz: 980dd1edb9894bf269af62688df3994f56e09ec7bed83f5f7b6abfa5022ccd86704bf800bdb8454290f5d8744d1a78c11946fa84e433d226fbbe084df5055b05
7
+ data.tar.gz: 91ffdf9a711c1f54e5de205bdbbe98c69f5e9b8917ce33197a5be6ed2241f041a19f85075f1f1ef4a129da0abb10c957248a40f16ab4d88a4690461123c884ad
data/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  When you have a valid token, simply instantiate the `ProductHunt::Client` as follows:
17
17
 
18
- ```
18
+ ```ruby
19
19
  client = ProductHunt::Client.new('mytoken')
20
20
  ```
21
21
 
@@ -25,6 +25,39 @@ client = ProductHunt::Client.new('mytoken')
25
25
  `hunting_season` is a work-in-progress, please [contribute](#contributing) if you need additional functionality.
26
26
 
27
27
 
28
+ ### [posts#index - Get the posts of today](https://api.producthunt.com/v1/docs/posts/posts_index_get_the_posts_of_today)
29
+
30
+ Look up today's posts.
31
+
32
+ Post attributes are listed in the API docs and accessed like `post["name"]`, `post["id"]`, etc.
33
+
34
+ Example:
35
+ ```ruby
36
+ client = ProductHunt::Client.new('mytoken')
37
+
38
+ posts = client.posts
39
+ posts.size # -> 14
40
+ posts[0]["name"] # -> "Content Marketing Stack"
41
+ posts[0]["id"] # -> 30425
42
+ ```
43
+
44
+
45
+ ### [posts#all - Get all the newest posts](https://api.producthunt.com/v1/docs/posts/posts_all_get_all_the_newest_posts)
46
+
47
+ Look up all posts.
48
+
49
+ Post attributes are listed in the API docs and accessed like `post["name"]`, `post["id"]`, etc.
50
+
51
+ Example:
52
+ ```ruby
53
+ client = ProductHunt::Client.new('mytoken')
54
+
55
+ posts = client.all_posts(per_page: 1, order: 'asc')
56
+ posts[0]["name"] # -> "Ferro"
57
+ posts[0]["id"] # -> 3
58
+ ```
59
+
60
+
28
61
  ### [posts#show - Get details of a post](https://api.producthunt.com/v1/docs/posts/posts_show_get_details_of_a_post)
29
62
 
30
63
  Look up a post using a required numeric ID.
@@ -32,7 +65,7 @@ Look up a post using a required numeric ID.
32
65
  Post attributes are listed in the API docs and accessed like `post["name"]`, `post["id"]`, etc.
33
66
 
34
67
  Example:
35
- ```
68
+ ```ruby
36
69
  client = ProductHunt::Client.new('mytoken')
37
70
 
38
71
  post = client.post(3372)
@@ -50,7 +83,7 @@ Look up a post's votes, with optional ordering and pagination.
50
83
  Post attributes are listed in the API docs and accessed like `vote["user"]`, `vote["id"]`, etc.
51
84
 
52
85
  Example, look up a post's votes and paginate through them in ascending order:
53
- ```
86
+ ```ruby
54
87
  client = ProductHunt::Client.new('mytoken')
55
88
  post = client.post(3372)
56
89
 
@@ -68,6 +101,21 @@ votes_page_2[0]["id"]
68
101
  ```
69
102
 
70
103
 
104
+ ### [users#index - Get all users](https://api.producthunt.com/v1/docs/users/users_index_get_all_users)
105
+
106
+ Get all users using ordering and pagination as noted in the official API docs.
107
+
108
+ Example:
109
+ ```ruby
110
+ client = ProductHunt::Client.new('mytoken')
111
+
112
+ users = client.users(order: 'asc')
113
+ users.first["name"] # -> "Nathan Bashaw"
114
+ users.first["headline"] # -> "Working on something new :)"
115
+ users.first["id"] # -> 1
116
+ ```
117
+
118
+
71
119
  ### [users#show - Get details of a user](https://api.producthunt.com/v1/docs/users/users_show_get_details_of_a_user)
72
120
 
73
121
  Look up a user by username or id.
@@ -75,7 +123,7 @@ Look up a user by username or id.
75
123
  User attributes are listed in the API docs and accessed like `user["name"]`, `user["headline"]`, etc.
76
124
 
77
125
  Example:
78
- ```
126
+ ```ruby
79
127
  client = ProductHunt::Client.new('mytoken')
80
128
  user = client.user('rrhoover')
81
129
  user["name"]
@@ -90,7 +138,7 @@ user["headline"]
90
138
  Look up a post's comments, with optional ordering and pagination.
91
139
 
92
140
  Example, look up a post's comments and paginate through them in ascending order:
93
- ```
141
+ ```ruby
94
142
  client = ProductHunt::Client.new('mytoken')
95
143
  post = client.post(3372)
96
144
 
@@ -115,7 +163,7 @@ For some API responses, an ID reference to or partial details for an associated
115
163
  Currently `#post` and `#user` apply when the associated record is present.
116
164
 
117
165
  Example:
118
- ```
166
+ ```ruby
119
167
  comment = ProductHunt::Client.new('mytoken').post(3372).comments(order: 'asc').first
120
168
 
121
169
  user_hash = comment["user"] # this will access the partial user details embedded in the response to the #comments call above
@@ -137,13 +185,37 @@ post_object["name"]
137
185
  # => "namevine"
138
186
  ```
139
187
 
188
+
189
+ ## ETAG Support
190
+
191
+ You can retrieve the etag for any call by calling `#etag` against the returned object or collection:
192
+
193
+ ```ruby
194
+ client = ProductHunt::Client.new('mytoken')
195
+ post = client.post(3372)
196
+ etag = post.etag
197
+ ```
198
+
199
+ You then can leverage [Product Hunt's API support](https://api.producthunt.com/v1/docs/example_performance_tips/use_the_e-tag_http_header) to increase performance by passing this etag on subsequent requests. If a record has NOT changed, it will respond to `#modified?` with false.
200
+
201
+ ```ruby
202
+ post = client.post(3372, headers: { 'If-None-Match': etag }) # pass as custom header
203
+ post = client.post(3372, etag: etag) # OR explicitly
204
+
205
+ if post.modified?
206
+ # do something with the modified post
207
+ else
208
+ # the post remains unmodified, trying to access any attributes on this object will raise an exception
209
+ end
210
+ ```
211
+
140
212
  ## Tests
141
213
 
142
214
  There are two ways to run tests:
143
215
 
144
- 1. `env TOKEN=mytoken bundle exec rake` which stubs out all of the calls to Product Hunt's API to local files.
216
+ 1. `bundle exec rake` which stubs out all of the calls to Product Hunt's API to local files.
145
217
 
146
- 2. `env TOKEN=mytoken SKIP_CALL_STUBS=true bundle exec rake` which runs tests against live data from the Product Hunt API.
218
+ 2. `TOKEN=mytoken USE_LIVE_API=true bundle exec rake` which runs tests against live data from the Product Hunt API using your developer token.
147
219
 
148
220
 
149
221
  ## Contributing
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -9,4 +9,3 @@ require 'product_hunt/user'
9
9
  require 'product_hunt/post'
10
10
  require 'product_hunt/vote'
11
11
  require 'product_hunt/comment'
12
-
@@ -5,20 +5,33 @@ module ProductHunt
5
5
  PATH = "/posts"
6
6
 
7
7
  def posts(options = {})
8
- fetch(PATH, options)["posts"].map{ |post| Post.new(post, self) }
8
+ process(PATH, options) do |response|
9
+ response["posts"].map{ |post| Post.new(post, self) }
10
+ end
11
+ end
12
+
13
+ def all_posts(options = {})
14
+ process(PATH + "/all", options) do |response|
15
+ response["posts"].map{ |post| Post.new(post, self) }
16
+ end
9
17
  end
10
18
 
11
19
  def post(id, options = {})
12
- post = fetch(PATH + "/#{id}", options)["post"]
13
- Post.new(post, self)
20
+ process(PATH + "/#{id}", options) do |response|
21
+ Post.new(response["post"], self)
22
+ end
14
23
  end
15
24
 
16
25
  def comments_for_post(id, options = {})
17
- fetch(PATH + "/#{id}/comments", options)["comments"].map{ |c| Comment.new(c, self) }
26
+ process(PATH + "/#{id}/comments", options) do |response|
27
+ response["comments"].map{ |c| Comment.new(c, self) }
28
+ end
18
29
  end
19
30
 
20
31
  def votes_for_post(id, options = {})
21
- fetch(PATH + "/#{id}/votes", options)["votes"].map{ |c| Vote.new(c, self) }
32
+ process(PATH + "/#{id}/votes", options) do |response|
33
+ response["votes"].map{ |c| Vote.new(c, self) }
34
+ end
22
35
  end
23
36
  end
24
37
  end
@@ -2,11 +2,25 @@ module ProductHunt
2
2
  module API
3
3
  module Users
4
4
 
5
- PATH = "/users"
5
+ USERS_PATH = "/users"
6
+ CURRENT_USER_PATH = "/me"
7
+
8
+ def users(options = {})
9
+ process(USERS_PATH, options) do |response|
10
+ response["users"].map{ |user| User.new(user, self) }
11
+ end
12
+ end
6
13
 
7
14
  def user(id, options = {})
8
- user = fetch(PATH + "/#{id}", options)["user"]
9
- User.new(user, self)
15
+ process(USERS_PATH + "/#{id}", options) do |response|
16
+ User.new(response["user"], self)
17
+ end
18
+ end
19
+
20
+ def current_user(options = {})
21
+ process(CURRENT_USER_PATH, options) do |response|
22
+ User.new(response["user"], self)
23
+ end
10
24
  end
11
25
 
12
26
  end
@@ -13,16 +13,53 @@ module ProductHunt
13
13
  @config = { headers: { "Authorization" => "Bearer #{token}" } }
14
14
  end
15
15
 
16
- def config
17
- @config
18
- end
19
-
20
16
  def fetch(path, params)
17
+ config = @config
18
+
19
+ if params.has_key?(:headers)
20
+ headers = params.delete(:headers)
21
+ config = config.merge({headers: config[:headers].merge(headers)})
22
+ end
23
+
24
+ if params.has_key?(:etag)
25
+ etag = params.delete(:etag)
26
+ config = config.merge({headers: config[:headers].merge({'If-None-Match' => etag})})
27
+ end
28
+
21
29
  queryopts = if params.is_a?(Enumerable) && params.size > 0
22
30
  "?" + URI.encode_www_form(params)
23
31
  end
24
32
 
25
- self.class.get(path + (queryopts || ""), @config)
33
+ self.class.get(path + (queryopts || ""), config)
26
34
  end
35
+
36
+ def process(path, params)
37
+ response = fetch(path, params)
38
+ processed_response = nil
39
+
40
+ fail "Block required to process response" if !block_given?
41
+
42
+ if response.code == 200
43
+ processed_response = yield response
44
+ processed_response.define_singleton_method(:modified?) { true }
45
+ elsif response.code == 304
46
+ processed_response.define_singleton_method(:modified?) { false }
47
+ processed_response.define_singleton_method(:method_missing) do |symbol, args|
48
+ raise InvalidAccessToUnmodifiedRecordError.new("Trying to call `#{symbol}`")
49
+ end
50
+ else
51
+ fail "Still need to cover the other response codes and use cases for the API (eg. 304 not modified, error cases)"
52
+ end
53
+
54
+ if response.headers["etag"]
55
+ fail "Object already defines #etag method" if processed_response.respond_to?(:etag)
56
+ processed_response.define_singleton_method(:etag) { response.headers["etag"].gsub!(/\A"|"\z/, '') }
57
+ end
58
+
59
+ processed_response
60
+ end
61
+ end
62
+
63
+ class InvalidAccessToUnmodifiedRecordError < StandardError
27
64
  end
28
65
  end
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hunting_season
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Jarema
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-02 00:00:00.000000000 Z
11
+ date: 2015-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: webmock
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1'
69
69
  description: Ruby gem which interfaces with Product Hunt's official REST API (api.producthunt.com).
@@ -87,7 +87,7 @@ files:
87
87
  - lib/product_hunt/post.rb
88
88
  - lib/product_hunt/user.rb
89
89
  - lib/product_hunt/vote.rb
90
- homepage: http://rubygems.org/gems/hunting_season
90
+ homepage: https://github.com/mikejarema/hunting_season
91
91
  licenses:
92
92
  - MIT
93
93
  metadata: {}
@@ -97,17 +97,17 @@ require_paths:
97
97
  - lib
98
98
  required_ruby_version: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - ! '>='
100
+ - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  requirements:
105
- - - ! '>='
105
+ - - ">="
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  requirements: []
109
109
  rubyforge_project:
110
- rubygems_version: 2.2.2
110
+ rubygems_version: 2.4.5
111
111
  signing_key:
112
112
  specification_version: 4
113
113
  summary: Ruby interface to producthunt.com's offical REST API.