redd 0.7.5 → 0.7.6
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/lib/redd.rb +1 -1
- data/lib/redd/clients/base/utilities.rb +4 -4
- data/lib/redd/error.rb +2 -1
- data/lib/redd/objects/comment.rb +1 -1
- data/lib/redd/objects/listing.rb +1 -1
- data/lib/redd/objects/subreddit.rb +14 -13
- data/lib/redd/rate_limit.rb +64 -26
- data/lib/redd/version.rb +1 -1
- data/redd.gemspec +1 -1
- data/spec/redd_spec.rb +0 -2
- data/spec/spec_helper.rb +2 -0
- metadata +5 -8
- data/spec/redd/rate_limit_spec.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9bef7701b48a6df684f8014d9514b6968406860
|
4
|
+
data.tar.gz: 65b56eae484015cea298b41ff8f8f254db735e4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e35f19510578de13aedbfb4ba552e9de82d3360cc041e4d5a2d5c6fc7aa0e46c6e3c5c9ffc09e4177e3a40adc4db95b08370b518dc8450f5adcf14ff1ca53c8
|
7
|
+
data.tar.gz: 4fb1df95bd17fd235d75a440f5dc6f508a6696f2f29479b5a64ee8cb498bd9f7489dd72cef3a489b23790487d0cbd72c65baac76c78e7068ac3291fb9d2b3450
|
data/lib/redd.rb
CHANGED
@@ -45,7 +45,7 @@ module Redd
|
|
45
45
|
# @param [Hash] body A JSON hash.
|
46
46
|
# @return [Objects::Thing, Objects::Listing]
|
47
47
|
def object_from_body(body)
|
48
|
-
return nil unless body.is_a?(Hash)
|
48
|
+
return nil unless body.is_a?(Hash)
|
49
49
|
object = object_from_kind(body[:kind])
|
50
50
|
flat = flatten_body(body)
|
51
51
|
object.new(self, flat)
|
@@ -73,8 +73,6 @@ module Redd
|
|
73
73
|
flattened
|
74
74
|
end
|
75
75
|
|
76
|
-
private
|
77
|
-
|
78
76
|
# Get a given property of a given object.
|
79
77
|
# @param [Objects::Base, String] object The object with the property.
|
80
78
|
# @param [Symbol] property The property to get.
|
@@ -82,12 +80,14 @@ module Redd
|
|
82
80
|
object.respond_to?(property) ? object.send(property) : object.to_s
|
83
81
|
end
|
84
82
|
|
83
|
+
private
|
84
|
+
|
85
85
|
# Take a multilevel body ({kind: "tx", data: {...}}) and flatten it
|
86
86
|
# into something like {kind: "tx", ...}
|
87
87
|
# @param [Hash] body The response body.
|
88
88
|
# @return [Hash] The flattened hash.
|
89
89
|
def flatten_body(body)
|
90
|
-
data = body[:data]
|
90
|
+
data = body[:data] || body
|
91
91
|
data[:kind] = body[:kind]
|
92
92
|
data
|
93
93
|
end
|
data/lib/redd/error.rb
CHANGED
@@ -27,6 +27,7 @@ module Redd
|
|
27
27
|
when /wrong_password/i then InvalidCredentials
|
28
28
|
when /bad_captcha/i then InvalidCaptcha
|
29
29
|
when /ratelimit/i then RateLimited
|
30
|
+
when /quota_filled/i then RateLimited
|
30
31
|
when /bad_css_name/i then InvalidClassName
|
31
32
|
when /too_old/i then Archived
|
32
33
|
when /too_much_flair_css/i then TooManyClassNames
|
@@ -120,7 +121,7 @@ module Redd
|
|
120
121
|
attr_reader :time
|
121
122
|
|
122
123
|
def initialize(env)
|
123
|
-
@time = env[:body][:json][:ratelimit]
|
124
|
+
@time = env[:body][:json][:ratelimit] || 60*60
|
124
125
|
super
|
125
126
|
end
|
126
127
|
end
|
data/lib/redd/objects/comment.rb
CHANGED
data/lib/redd/objects/listing.rb
CHANGED
@@ -41,7 +41,7 @@ module Redd
|
|
41
41
|
resubmit: resubmit, sendreplies: sendreplies
|
42
42
|
}
|
43
43
|
|
44
|
-
params
|
44
|
+
params.merge!(captcha: captcha, iden: identifier) if captcha
|
45
45
|
params[:kind], params[:text] = :self, text if text
|
46
46
|
params[:kind], params[:url] = :link, url if url
|
47
47
|
|
@@ -150,15 +150,16 @@ module Redd
|
|
150
150
|
# @param [String] text The text to set the flair to.
|
151
151
|
# @param [String] css_class The css_class of the flair.
|
152
152
|
def set_flair(thing, type = nil, text = nil, css_class = nil)
|
153
|
+
params = {text: text, css_class: css_class}
|
153
154
|
if thing.is_a?(Objects::User) || type == :user
|
154
155
|
params[:name] = client.property(thing, :name)
|
155
|
-
elsif thing.is_a?(Objects::Submission) || type == :
|
156
|
+
elsif thing.is_a?(Objects::Submission) || type == :link
|
156
157
|
params[:link] = client.property(thing, :fullname)
|
157
158
|
else
|
158
159
|
fail "You should provide a proper type."
|
159
160
|
end
|
160
161
|
|
161
|
-
post("/r/#{display_name}/api/flair",
|
162
|
+
post("/r/#{display_name}/api/flair", params)
|
162
163
|
end
|
163
164
|
|
164
165
|
# @!endgroup
|
@@ -282,16 +283,16 @@ module Redd
|
|
282
283
|
else
|
283
284
|
about = admin_about
|
284
285
|
final = about
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
286
|
+
.select { |k, _| required.include?(k) }
|
287
|
+
.merge(
|
288
|
+
name: display_name,
|
289
|
+
type: about[:subreddit_type],
|
290
|
+
lang: about[:language],
|
291
|
+
link_type: about[:content_options],
|
292
|
+
allow_top: true,
|
293
|
+
css_on_cname: true
|
294
|
+
)
|
295
|
+
.merge(attributes)
|
295
296
|
params.merge!(final)
|
296
297
|
end
|
297
298
|
|
data/lib/redd/rate_limit.rb
CHANGED
@@ -1,50 +1,88 @@
|
|
1
1
|
# The main Redd module.
|
2
2
|
module Redd
|
3
|
-
# The class that handles rate limiting for reddit.
|
4
|
-
# X-Ratelimit headers but using those headers instead would just lead to
|
5
|
-
# short bursts, so it's better to go at a constant speed and space out
|
6
|
-
# requests every second.
|
3
|
+
# The class that handles rate limiting for reddit.
|
7
4
|
#
|
8
|
-
# If you'd rather have
|
5
|
+
# If you'd rather have an asynchronous or queue-based limiting, it's easy to
|
9
6
|
# write one yourself. A rate limiting class is any class that has an
|
10
7
|
# {#after_limit} method. The block returns a Faraday::Response object, so you
|
11
8
|
# can also extract the headers from the response and use those instead. To
|
12
9
|
# remove rate limiting entirely, follow the example below.
|
13
10
|
#
|
14
|
-
# @example
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# yield
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# client = Redd.it(..., rate_limit: IWantToGetIPBanned.new)
|
11
|
+
# @example To remove rate limiting entirely, just burst forever.
|
12
|
+
# rt = Redd::RateLimit.new
|
13
|
+
# rt.burst!(Float::INFINITY)
|
22
14
|
class RateLimit
|
23
|
-
# @!attribute [r] last_request_time
|
24
|
-
# @return [Time] The time when the last request took place.
|
25
|
-
attr_reader :last_request_time
|
26
|
-
|
27
15
|
# @!attribute [rw] gap
|
28
16
|
# @return [Integer, Float] The minimum time between requests.
|
29
17
|
attr_accessor :gap
|
30
18
|
|
19
|
+
# @!attribute [rw] burst_length
|
20
|
+
# @return [Integer] The number of requests left to burst.
|
21
|
+
attr_accessor :burst_length
|
22
|
+
|
23
|
+
# @!attribute [r] last_request
|
24
|
+
# @return [Time] The time the last request was made.
|
25
|
+
attr_reader :last_request
|
26
|
+
|
27
|
+
# @!attribute [r] used
|
28
|
+
# @!attribute [r] remaining
|
29
|
+
# @!attribute [r] reset
|
30
|
+
# @return [Integer] The data from reddit's response headers.
|
31
|
+
attr_reader :used, :remaining, :reset
|
32
|
+
|
31
33
|
# @param [Float, Integer] gap The minimum time between each request.
|
32
34
|
def initialize(gap)
|
33
35
|
# Some time ages ago, because we never made a request.
|
34
|
-
@
|
36
|
+
@last_request = Time.at(0)
|
35
37
|
@gap = gap
|
38
|
+
@burst_length = 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# Don't sleep for the next few requests.
|
42
|
+
# @param [Integer] times The number of times to ignore limiting.
|
43
|
+
# @return [Integer] The total times rate limiting will be ignored.
|
44
|
+
def burst!(times)
|
45
|
+
@burst_length += times
|
36
46
|
end
|
37
47
|
|
38
|
-
# Sleep until
|
39
|
-
# given request.
|
48
|
+
# Sleep until 1 second has passed since the last request and perform the
|
49
|
+
# given request unless bursting.
|
40
50
|
#
|
41
|
-
# @yield A
|
42
|
-
# @return The
|
51
|
+
# @yield [Faraday::Response] A response.
|
52
|
+
# @return [Faraday::Response] The response.
|
43
53
|
def after_limit
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
54
|
+
response = yield
|
55
|
+
update!(response)
|
56
|
+
sleep(wait_time)
|
57
|
+
response
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Update necessary info with each request.
|
63
|
+
# @param [Faraday::Response] response The response to the request made.
|
64
|
+
def update!(response)
|
65
|
+
@last_request = Time.now
|
66
|
+
%w(used remaining reset).each do |type|
|
67
|
+
value = response.headers["x-ratelimit-#{type}"]
|
68
|
+
instance_variable_set("@#{type}", value.to_i) unless value.nil?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Float, Integer] The number of seconds to sleep.
|
73
|
+
def wait_time
|
74
|
+
if @burst_length > 0 && @remaining > 0
|
75
|
+
# Don't sleep if we are in burst mode.
|
76
|
+
@burst_length -= 1
|
77
|
+
0
|
78
|
+
elsif @reset.nil? || @remaining.nil?
|
79
|
+
# Just guess if no headers were given (max 1 sec after last request).
|
80
|
+
time = @last_request_time - Time.now + @gap
|
81
|
+
time > 0 ? time : 0
|
82
|
+
else
|
83
|
+
# Most cases, spread out requests over available time.
|
84
|
+
@reset.to_f / (@gap * @remaining + 1)
|
85
|
+
end
|
48
86
|
end
|
49
87
|
end
|
50
88
|
end
|
data/lib/redd/version.rb
CHANGED
data/redd.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.9.4"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.4.2"
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.2.0"
|
24
24
|
spec.add_development_dependency "vcr", "~> 2.9.3"
|
data/spec/redd_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -40,6 +40,8 @@ RSpec.configure do |config|
|
|
40
40
|
config.filter_run_including :focus
|
41
41
|
config.run_all_when_everything_filtered = true
|
42
42
|
|
43
|
+
# If we don't have the details to perform authentication, we can't do those
|
44
|
+
# tests.
|
43
45
|
if ENV["TRAVIS_SECURE_ENV_VARS"] == "false"
|
44
46
|
config.filter_run_excluding :secure
|
45
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Avinash Dwarapu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.9.4
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.9.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -194,7 +194,6 @@ files:
|
|
194
194
|
- lib/redd/version.rb
|
195
195
|
- redd.gemspec
|
196
196
|
- spec/redd/objects/base_spec.rb
|
197
|
-
- spec/redd/rate_limit_spec.rb
|
198
197
|
- spec/redd/response/parse_json_spec.rb
|
199
198
|
- spec/redd/response/raise_error_spec.rb
|
200
199
|
- spec/redd_spec.rb
|
@@ -219,15 +218,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
218
|
version: '0'
|
220
219
|
requirements: []
|
221
220
|
rubyforge_project:
|
222
|
-
rubygems_version: 2.
|
221
|
+
rubygems_version: 2.4.5
|
223
222
|
signing_key:
|
224
223
|
specification_version: 4
|
225
224
|
summary: A Reddit API Wrapper for Ruby.
|
226
225
|
test_files:
|
227
226
|
- spec/redd/objects/base_spec.rb
|
228
|
-
- spec/redd/rate_limit_spec.rb
|
229
227
|
- spec/redd/response/parse_json_spec.rb
|
230
228
|
- spec/redd/response/raise_error_spec.rb
|
231
229
|
- spec/redd_spec.rb
|
232
230
|
- spec/spec_helper.rb
|
233
|
-
has_rdoc:
|
@@ -1,29 +0,0 @@
|
|
1
|
-
RSpec.describe Redd::RateLimit do
|
2
|
-
let(:rate_limit) { Redd::RateLimit.new(2) }
|
3
|
-
|
4
|
-
it "waits two seconds between consecutive requests" do
|
5
|
-
rate_limit.after_limit {}
|
6
|
-
start_time = Time.now
|
7
|
-
rate_limit.after_limit {}
|
8
|
-
end_time = Time.now
|
9
|
-
|
10
|
-
expect(end_time - start_time).to be_within(0.1).of(2)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "doesn't wait if two seconds have passed since last request" do
|
14
|
-
rate_limit.after_limit {}
|
15
|
-
sleep(2)
|
16
|
-
start_time = Time.now
|
17
|
-
rate_limit.after_limit {}
|
18
|
-
end_time = Time.now
|
19
|
-
|
20
|
-
expect(end_time - start_time).to be_within(0.1).of(0)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "stores the time the last request was made" do
|
24
|
-
time = Time.now
|
25
|
-
rate_limit.after_limit {}
|
26
|
-
|
27
|
-
expect(rate_limit.last_request_time).to be_within(0.1).of(time)
|
28
|
-
end
|
29
|
-
end
|