reddit_api 0.1.4 → 0.1.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 +4 -4
- data/Rakefile +0 -17
- data/lib/reddit_api/client.rb +42 -70
- data/lib/reddit_api/requestor.rb +72 -0
- data/lib/reddit_api/subreddits.rb +6 -0
- data/lib/reddit_api/version.rb +1 -1
- data/lib/reddit_api.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9857234245fc7df4fa6eeb8c4ccc4cd9fc9cb0f
|
4
|
+
data.tar.gz: 4b50dbe9dec2cc73d0ca957d7dd57a673452c978
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43a6de736b1ebc6bb82a802d29336fd2dc471b4fd873b9c8fa3c30b9a7a9f680a89f55e689fb0d113546f6462c0e5765be08ff7c4171810b043cf63f0a5b9773
|
7
|
+
data.tar.gz: 41b3f5c0428b39bb0162ab65d70d7656cf23d1833f98d3e2abc323ea5afebc4d2f573ae10759fac4d79e9f088c58e6d55cf8abb0108dcb4e57f9a059edf9882f
|
data/Rakefile
CHANGED
@@ -1,19 +1,2 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
-
namespace :rspec do
|
4
|
-
|
5
|
-
desc "Runs all RSpec specs"
|
6
|
-
task :all do
|
7
|
-
set_environment("TEST")
|
8
|
-
run_all_specs
|
9
|
-
end
|
10
|
-
|
11
|
-
def set_environment(environment)
|
12
|
-
ENV["ENVIRONMENT"] = environment
|
13
|
-
end
|
14
|
-
|
15
|
-
def run_all_specs
|
16
|
-
system("rspec")
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
data/lib/reddit_api/client.rb
CHANGED
@@ -13,30 +13,37 @@ module RedditApi
|
|
13
13
|
|
14
14
|
attr_reader :agent, :id, :password, :secret, :username, :failures
|
15
15
|
|
16
|
-
MAXIMUM_RECORDS = 100
|
17
16
|
MAX_FAILURES = 5
|
18
17
|
ERROR_CODES = (400..511)
|
19
18
|
SLEEP_TIME = self.sleep_time
|
20
19
|
|
21
|
-
|
22
20
|
def initialize(args = {})
|
23
|
-
@agent = ENV["REDDIT_AGENT"]
|
24
21
|
@client = args.fetch(:client, HTTParty)
|
25
|
-
@
|
26
|
-
@password = ENV["REDDIT_AGENT"]
|
27
|
-
@secret = ENV["REDDIT_AGENT"]
|
28
|
-
@username = ENV["REDDIT_AGENT"]
|
29
|
-
@base_url = "https://oauth.reddit.com/"
|
22
|
+
@requestor = args.fetch(:requestor, RedditApi::Requestor.new(client: client))
|
30
23
|
@failures = args.fetch(:failures, 0)
|
31
24
|
@null_response_factory = RedditApi:: NullResponse
|
32
25
|
@last_record = nil
|
33
26
|
end
|
34
27
|
|
35
28
|
def get(endpoint, count, resource_type)
|
29
|
+
if count > 1
|
30
|
+
get_many(endpoint, count, resource_type)
|
31
|
+
else
|
32
|
+
get_one(endpoint, count, resource_type)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
attr_writer :failures, :last_record
|
38
|
+
private
|
39
|
+
attr_reader :client, :base_url, :null_response_factory, :last_record,
|
40
|
+
:requestor
|
41
|
+
|
42
|
+
def get_many(endpoint, count, resource_type)
|
36
43
|
sleep(SLEEP_TIME)
|
37
44
|
records = {}
|
38
45
|
loop do
|
39
|
-
new_records = request_records(endpoint, resource_type)
|
46
|
+
new_records = request_records(endpoint, resource_type, count)
|
40
47
|
collect_records(new_records, records, count)
|
41
48
|
break if break_get?(records, count)
|
42
49
|
end
|
@@ -44,10 +51,9 @@ module RedditApi
|
|
44
51
|
records.keys
|
45
52
|
end
|
46
53
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
attr_reader :client, :base_url, :null_response_factory, :last_record
|
54
|
+
def get_one(endpoint, count, resource_type)
|
55
|
+
request_records(endpoint, resource_type, count)
|
56
|
+
end
|
51
57
|
|
52
58
|
def collect_records(new_records, collected_records, count)
|
53
59
|
new_records.each do |record|
|
@@ -56,24 +62,22 @@ module RedditApi
|
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
59
|
-
def request_records(endpoint, resource_type)
|
65
|
+
def request_records(endpoint, resource_type, count)
|
60
66
|
response = send_request(endpoint, resource_type)
|
61
|
-
parse_response(response)
|
67
|
+
parse_response(response, count)
|
62
68
|
end
|
63
69
|
|
64
70
|
def send_request(endpoint, resource_type)
|
65
|
-
|
66
|
-
|
67
|
-
query = generate_query(resource_type)
|
68
|
-
response = client.get(url, headers: headers, query: query)
|
71
|
+
request = requestor.build(endpoint, resource_type, last_record)
|
72
|
+
response = client.get(*request)
|
69
73
|
response || null_response_factory.new
|
70
74
|
end
|
71
75
|
|
72
|
-
def parse_response(response)
|
76
|
+
def parse_response(response, count)
|
73
77
|
if bad_response?(response)
|
74
|
-
handle_bad_response
|
78
|
+
handle_bad_response(count)
|
75
79
|
else
|
76
|
-
handle_successful_response(response)
|
80
|
+
handle_successful_response(response, count)
|
77
81
|
end
|
78
82
|
end
|
79
83
|
|
@@ -81,16 +85,28 @@ module RedditApi
|
|
81
85
|
ERROR_CODES.cover?(response.code) || response["error"]
|
82
86
|
end
|
83
87
|
|
84
|
-
def handle_bad_response
|
88
|
+
def handle_bad_response(count)
|
85
89
|
self.failures += 1
|
86
|
-
|
90
|
+
if count > 1
|
91
|
+
[]
|
92
|
+
else
|
93
|
+
nil
|
94
|
+
end
|
87
95
|
end
|
88
96
|
|
89
|
-
def handle_successful_response(response)
|
97
|
+
def handle_successful_response(response, count)
|
98
|
+
if count > 1
|
99
|
+
handle_plural_response(response)
|
100
|
+
else
|
101
|
+
response
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def handle_plural_response(response)
|
90
106
|
if records = response["data"]["children"]
|
91
107
|
store_last_record(records)
|
92
108
|
else
|
93
|
-
|
109
|
+
handle_bad_response
|
94
110
|
end
|
95
111
|
end
|
96
112
|
|
@@ -103,49 +119,5 @@ module RedditApi
|
|
103
119
|
records.length >= desired_count || failures >= MAX_FAILURES
|
104
120
|
end
|
105
121
|
|
106
|
-
def generate_headers
|
107
|
-
access_token = generate_access_token
|
108
|
-
{
|
109
|
-
"Authorization" => "bearer #{access_token}",
|
110
|
-
"user-agent" => agent
|
111
|
-
}
|
112
|
-
end
|
113
|
-
|
114
|
-
def generate_query(resource_type)
|
115
|
-
{
|
116
|
-
limit: MAXIMUM_RECORDS,
|
117
|
-
after: generate_after(resource_type)
|
118
|
-
}
|
119
|
-
end
|
120
|
-
|
121
|
-
def generate_after(resource_type)
|
122
|
-
if last_record
|
123
|
-
build_after(resource_type)
|
124
|
-
else
|
125
|
-
nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def build_after(resource_type)
|
130
|
-
prefix = TYPE_PREFIXES[resource_type]
|
131
|
-
last_resource_id = last_record["data"]["id"]
|
132
|
-
"#{prefix}_#{last_resource_id}"
|
133
|
-
end
|
134
|
-
|
135
|
-
def generate_access_token
|
136
|
-
url = "https://www.reddit.com/api/v1/access_token"
|
137
|
-
basic_auth = { username: id,
|
138
|
-
password: secret }
|
139
|
-
headers = { "user-agent" => agent }
|
140
|
-
body = { grant_type: "password",
|
141
|
-
username: username,
|
142
|
-
password: password }
|
143
|
-
response = client.post(url,
|
144
|
-
basic_auth: basic_auth,
|
145
|
-
headers: headers,
|
146
|
-
body: body)
|
147
|
-
response["access_token"]
|
148
|
-
end
|
149
|
-
|
150
122
|
end
|
151
123
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
module RedditApi
|
3
|
+
class Requestor
|
4
|
+
|
5
|
+
MAXIMUM_RECORDS = 100
|
6
|
+
AGENT = ENV["REDDIT_AGENT"]
|
7
|
+
ID = ENV["REDDIT_AGENT"]
|
8
|
+
PASSWORD = ENV["REDDIT_AGENT"]
|
9
|
+
SECRET = ENV["REDDIT_AGENT"]
|
10
|
+
USERNAME = ENV["REDDIT_AGENT"]
|
11
|
+
BASE_URL = "https://oauth.reddit.com/"
|
12
|
+
|
13
|
+
def initialize(args = {})
|
14
|
+
@client = args.fetch(:client, HTTParty)
|
15
|
+
end
|
16
|
+
|
17
|
+
def build(endpoint, resource_type, last_record = nil)
|
18
|
+
url = BASE_URL + endpoint
|
19
|
+
headers = generate_headers
|
20
|
+
query = generate_query(resource_type, last_record)
|
21
|
+
[url, { headers: headers, query: query }]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
attr_reader :client
|
26
|
+
|
27
|
+
def generate_headers
|
28
|
+
access_token = generate_access_token
|
29
|
+
{
|
30
|
+
"Authorization" => "bearer #{access_token}",
|
31
|
+
"user-agent" => AGENT
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_query(resource_type, last_record)
|
36
|
+
{
|
37
|
+
limit: MAXIMUM_RECORDS,
|
38
|
+
after: generate_after(resource_type, last_record)
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_after(resource_type, last_record)
|
43
|
+
if last_record
|
44
|
+
build_after(resource_type, last_record)
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_after(resource_type, record)
|
51
|
+
prefix = TYPE_PREFIXES[resource_type]
|
52
|
+
last_resource_id = record["data"]["id"]
|
53
|
+
"#{prefix}_#{last_resource_id}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_access_token
|
57
|
+
url = "https://www.reddit.com/api/v1/access_token"
|
58
|
+
basic_auth = { username: ID,
|
59
|
+
password: SECRET }
|
60
|
+
headers = { "user-agent" => AGENT }
|
61
|
+
body = { grant_type: "password",
|
62
|
+
username: USERNAME,
|
63
|
+
password: PASSWORD }
|
64
|
+
response = client.post(url,
|
65
|
+
basic_auth: basic_auth,
|
66
|
+
headers: headers,
|
67
|
+
body: body)
|
68
|
+
response["access_token"]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -12,6 +12,12 @@ module RedditApi
|
|
12
12
|
build_all_subreddits(subreddits_data)
|
13
13
|
end
|
14
14
|
|
15
|
+
def data_for(subreddit)
|
16
|
+
endpoint = "r/#{subreddit.name}/about.json"
|
17
|
+
response = client.get(endpoint, 1, :subreddit)
|
18
|
+
build_subreddit(response)
|
19
|
+
end
|
20
|
+
|
15
21
|
private
|
16
22
|
attr_reader :client, :subreddit_factory
|
17
23
|
|
data/lib/reddit_api/version.rb
CHANGED
data/lib/reddit_api.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reddit_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Fuentes
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- lib/reddit_api/null_response.rb
|
150
150
|
- lib/reddit_api/post.rb
|
151
151
|
- lib/reddit_api/posts.rb
|
152
|
+
- lib/reddit_api/requestor.rb
|
152
153
|
- lib/reddit_api/resource_type_prefixes.rb
|
153
154
|
- lib/reddit_api/subreddit.rb
|
154
155
|
- lib/reddit_api/subreddits.rb
|