hunting_season 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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.