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 +5 -13
- data/README.md +80 -8
- data/VERSION +1 -1
- data/lib/hunting_season.rb +0 -1
- data/lib/product_hunt/api/posts.rb +18 -5
- data/lib/product_hunt/api/users.rb +17 -3
- data/lib/product_hunt/client.rb +42 -5
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZTEyYzI5ZTlhMTcxMmZhZjcwZTdhMTA5MjNlNDQ0M2VlZWE2ZjhhYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d5b4c9215d09f4fc84654338062e0b28c3e6147b
|
4
|
+
data.tar.gz: 8f0e9c7c28d45278e28ad041bff6f43ead27e953
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
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. `
|
216
|
+
1. `bundle exec rake` which stubs out all of the calls to Product Hunt's API to local files.
|
145
217
|
|
146
|
-
2. `
|
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.
|
1
|
+
0.0.5
|
data/lib/hunting_season.rb
CHANGED
@@ -5,20 +5,33 @@ module ProductHunt
|
|
5
5
|
PATH = "/posts"
|
6
6
|
|
7
7
|
def posts(options = {})
|
8
|
-
|
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
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
9
|
-
|
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
|
data/lib/product_hunt/client.rb
CHANGED
@@ -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 || ""),
|
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
|
+
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-
|
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:
|
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.
|
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.
|