redd 0.8.8 → 0.9.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/CONTRIBUTING.md +63 -0
  4. data/Guardfile +7 -0
  5. data/README.md +6 -5
  6. data/Rakefile +1 -1
  7. data/TODO.md +423 -0
  8. data/bin/console +91 -77
  9. data/bin/guard +2 -0
  10. data/lib/redd.rb +7 -5
  11. data/lib/redd/api_client.rb +2 -3
  12. data/lib/redd/auth_strategies/auth_strategy.rb +7 -2
  13. data/lib/redd/auth_strategies/script.rb +7 -0
  14. data/lib/redd/auth_strategies/userless.rb +7 -0
  15. data/lib/redd/auth_strategies/web.rb +6 -1
  16. data/lib/redd/client.rb +0 -3
  17. data/lib/redd/errors.rb +56 -0
  18. data/lib/redd/middleware.rb +10 -8
  19. data/lib/redd/models/access.rb +30 -18
  20. data/lib/redd/models/comment.rb +185 -27
  21. data/lib/redd/models/front_page.rb +16 -36
  22. data/lib/redd/models/gildable.rb +1 -1
  23. data/lib/redd/models/inboxable.rb +13 -3
  24. data/lib/redd/models/listing.rb +27 -6
  25. data/lib/redd/models/live_thread.rb +76 -23
  26. data/lib/redd/models/live_update.rb +46 -0
  27. data/lib/redd/models/messageable.rb +1 -1
  28. data/lib/redd/models/mod_action.rb +59 -0
  29. data/lib/redd/models/model.rb +23 -0
  30. data/lib/redd/models/moderatable.rb +6 -6
  31. data/lib/redd/models/modmail.rb +61 -0
  32. data/lib/redd/models/modmail_conversation.rb +154 -0
  33. data/lib/redd/models/modmail_message.rb +35 -0
  34. data/lib/redd/models/more_comments.rb +29 -5
  35. data/lib/redd/models/multireddit.rb +63 -20
  36. data/lib/redd/models/paginated_listing.rb +113 -0
  37. data/lib/redd/models/postable.rb +11 -13
  38. data/lib/redd/models/private_message.rb +78 -11
  39. data/lib/redd/models/replyable.rb +2 -2
  40. data/lib/redd/models/reportable.rb +14 -0
  41. data/lib/redd/models/searchable.rb +2 -2
  42. data/lib/redd/models/self.rb +17 -0
  43. data/lib/redd/models/session.rb +75 -31
  44. data/lib/redd/models/submission.rb +309 -56
  45. data/lib/redd/models/subreddit.rb +330 -103
  46. data/lib/redd/models/trophy.rb +34 -0
  47. data/lib/redd/models/user.rb +185 -46
  48. data/lib/redd/models/wiki_page.rb +37 -16
  49. data/lib/redd/utilities/error_handler.rb +13 -13
  50. data/lib/redd/utilities/unmarshaller.rb +7 -5
  51. data/lib/redd/version.rb +1 -1
  52. data/redd.gemspec +18 -15
  53. metadata +82 -16
  54. data/lib/redd/error.rb +0 -53
  55. data/lib/redd/models/basic_model.rb +0 -80
  56. data/lib/redd/models/lazy_model.rb +0 -75
  57. data/lib/redd/models/mod_mail.rb +0 -142
  58. data/lib/redd/utilities/stream.rb +0 -61
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Redd
4
- VERSION = '0.8.8'
4
+ VERSION = '0.9.0.pre.1'
5
5
  end
@@ -1,35 +1,38 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  lib = File.expand_path('../lib', __FILE__)
5
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
5
  require 'redd/version'
7
6
 
8
- Gem::Specification.new do |spec|
9
- spec.name = 'redd'
10
- spec.version = Redd::VERSION
11
- spec.authors = ['Avinash Dwarapu']
12
- spec.email = ['avinash@dwarapu.me']
7
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
8
+ spec.name = 'redd'
9
+ spec.version = Redd::VERSION
10
+ spec.authors = ['Avinash Dwarapu']
11
+ spec.email = ['avinash@dwarapu.me']
12
+ spec.summary = 'A batteries-included API wrapper for reddit.'
13
+ spec.homepage = 'https://github.com/avinashbot/redd'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 2.1.0'
13
16
 
14
- spec.summary = 'A batteries-included API wrapper for reddit.'
15
- spec.homepage = 'https://github.com/avinashbot/redd'
16
- spec.license = 'MIT'
17
-
18
- spec.files = `git ls-files -z`
19
- .split("\x0")
20
- .reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
21
20
  spec.bindir = 'exe'
22
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
22
  spec.require_paths = ['lib']
24
23
 
25
24
  spec.add_dependency 'http', '~> 2.2'
25
+ spec.add_dependency 'lazy_lazer', '~> 0.6'
26
26
 
27
+ spec.add_development_dependency 'pry', '~> 0.10'
27
28
  spec.add_development_dependency 'bundler', '~> 1.14'
28
29
  spec.add_development_dependency 'rake', '~> 12.0'
29
- spec.add_development_dependency 'rubocop', '~> 0.47'
30
- spec.add_development_dependency 'pry', '~> 0.10'
30
+ spec.add_development_dependency 'yard', '~> 0.9.9'
31
+ spec.add_development_dependency 'rubocop', '~> 0.50'
31
32
 
32
33
  spec.add_development_dependency 'rspec', '~> 3.5'
34
+ spec.add_development_dependency 'guard', '~> 2.14'
35
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
33
36
  spec.add_development_dependency 'simplecov', '~> 0.13'
34
37
  spec.add_development_dependency 'webmock', '~> 2.3'
35
38
  spec.add_development_dependency 'vcr', '~> 3.0'
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.8.8
4
+ version: 0.9.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Avinash Dwarapu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-02 00:00:00.000000000 Z
11
+ date: 2017-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: lazy_lazer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +81,33 @@ dependencies:
53
81
  - !ruby/object:Gem::Version
54
82
  version: '12.0'
55
83
  - !ruby/object:Gem::Dependency
56
- name: rubocop
84
+ name: yard
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '0.47'
89
+ version: 0.9.9
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '0.47'
96
+ version: 0.9.9
69
97
  - !ruby/object:Gem::Dependency
70
- name: pry
98
+ name: rubocop
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
101
  - - "~>"
74
102
  - !ruby/object:Gem::Version
75
- version: '0.10'
103
+ version: '0.50'
76
104
  type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
108
  - - "~>"
81
109
  - !ruby/object:Gem::Version
82
- version: '0.10'
110
+ version: '0.50'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: rspec
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +122,34 @@ dependencies:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
124
  version: '3.5'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.14'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.14'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '4.7'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '4.7'
97
153
  - !ruby/object:Gem::Dependency
98
154
  name: simplecov
99
155
  requirement: !ruby/object:Gem::Requirement
@@ -148,11 +204,15 @@ files:
148
204
  - ".rspec"
149
205
  - ".rubocop.yml"
150
206
  - ".travis.yml"
207
+ - CONTRIBUTING.md
151
208
  - Gemfile
209
+ - Guardfile
152
210
  - LICENSE.txt
153
211
  - README.md
154
212
  - Rakefile
213
+ - TODO.md
155
214
  - bin/console
215
+ - bin/guard
156
216
  - bin/setup
157
217
  - lib/redd.rb
158
218
  - lib/redd/api_client.rb
@@ -161,34 +221,40 @@ files:
161
221
  - lib/redd/auth_strategies/userless.rb
162
222
  - lib/redd/auth_strategies/web.rb
163
223
  - lib/redd/client.rb
164
- - lib/redd/error.rb
224
+ - lib/redd/errors.rb
165
225
  - lib/redd/middleware.rb
166
226
  - lib/redd/models/access.rb
167
- - lib/redd/models/basic_model.rb
168
227
  - lib/redd/models/comment.rb
169
228
  - lib/redd/models/front_page.rb
170
229
  - lib/redd/models/gildable.rb
171
230
  - lib/redd/models/inboxable.rb
172
- - lib/redd/models/lazy_model.rb
173
231
  - lib/redd/models/listing.rb
174
232
  - lib/redd/models/live_thread.rb
233
+ - lib/redd/models/live_update.rb
175
234
  - lib/redd/models/messageable.rb
176
- - lib/redd/models/mod_mail.rb
235
+ - lib/redd/models/mod_action.rb
236
+ - lib/redd/models/model.rb
177
237
  - lib/redd/models/moderatable.rb
238
+ - lib/redd/models/modmail.rb
239
+ - lib/redd/models/modmail_conversation.rb
240
+ - lib/redd/models/modmail_message.rb
178
241
  - lib/redd/models/more_comments.rb
179
242
  - lib/redd/models/multireddit.rb
243
+ - lib/redd/models/paginated_listing.rb
180
244
  - lib/redd/models/postable.rb
181
245
  - lib/redd/models/private_message.rb
182
246
  - lib/redd/models/replyable.rb
247
+ - lib/redd/models/reportable.rb
183
248
  - lib/redd/models/searchable.rb
249
+ - lib/redd/models/self.rb
184
250
  - lib/redd/models/session.rb
185
251
  - lib/redd/models/submission.rb
186
252
  - lib/redd/models/subreddit.rb
253
+ - lib/redd/models/trophy.rb
187
254
  - lib/redd/models/user.rb
188
255
  - lib/redd/models/wiki_page.rb
189
256
  - lib/redd/utilities/error_handler.rb
190
257
  - lib/redd/utilities/rate_limiter.rb
191
- - lib/redd/utilities/stream.rb
192
258
  - lib/redd/utilities/unmarshaller.rb
193
259
  - lib/redd/version.rb
194
260
  - logo.png
@@ -205,12 +271,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
205
271
  requirements:
206
272
  - - ">="
207
273
  - !ruby/object:Gem::Version
208
- version: '0'
274
+ version: 2.1.0
209
275
  required_rubygems_version: !ruby/object:Gem::Requirement
210
276
  requirements:
211
- - - ">="
277
+ - - ">"
212
278
  - !ruby/object:Gem::Version
213
- version: '0'
279
+ version: 1.3.1
214
280
  requirements: []
215
281
  rubyforge_project:
216
282
  rubygems_version: 2.6.8
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Redd
4
- # An error raised by {Redd::Middleware} when there was an error returned by reddit.
5
- class TokenRetrievalError < StandardError; end
6
-
7
- # An error with the API.
8
- class APIError < StandardError
9
- attr_reader :response, :name
10
-
11
- def initialize(response)
12
- @response = response
13
- @name, message = response.body[:json][:errors][0]
14
- super(message)
15
- end
16
- end
17
-
18
- # Represents an error from reddit returned in a response.
19
- class ResponseError < StandardError
20
- attr_accessor :response
21
-
22
- def initialize(response)
23
- super(response.raw_body.length <= 80 ? response.raw_body : "#{response.raw_body[0..80]}...")
24
- @response = response
25
- end
26
- end
27
-
28
- # An error returned by AuthStrategy.
29
- # @note A common cause of this error is not having a bot account registered as a developer on
30
- # the app.
31
- class AuthenticationError < ResponseError; end
32
-
33
- # An error with Redd, probably (let me know!)
34
- class BadRequest < ResponseError; end
35
-
36
- # Whatever it is, you're not allowed to do it.
37
- class Forbidden < ResponseError; end
38
-
39
- # You don't have the correct scope to do this.
40
- class InsufficientScope < ResponseError; end
41
-
42
- # The access object supplied was invalid.
43
- class InvalidAccess < ResponseError; end
44
-
45
- # Returned when reddit raises a 404 error.
46
- class NotFound < ResponseError; end
47
-
48
- # Too many requests and not enough rate limiting.
49
- class TooManyRequests < ResponseError; end
50
-
51
- # An unknown error on reddit's end. Usually fixed with a retry.
52
- class ServerError < ResponseError; end
53
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Redd
4
- module Models
5
- # The base class for all models.
6
- class BasicModel
7
- # @abstract Create an instance from a value.
8
- # @param _client [APIClient] the api client to initialize the object with
9
- # @param _value [Object] the object to coerce
10
- # @return [BasicModel]
11
- def self.from_id(_client, _value)
12
- # TODO: abstract this out?
13
- raise "coercion not implemented for #{name}"
14
- end
15
-
16
- # @return [APIClient] the client the model was initialized with
17
- attr_reader :client
18
-
19
- # Create a non-lazily initialized class.
20
- # @param client [APIClient] the client that the model uses to make requests
21
- # @param attributes [Hash] the class's attributes
22
- def initialize(client, attributes = {})
23
- @client = client
24
- @attributes = attributes
25
- after_initialize
26
- end
27
-
28
- # @return [Hash] a Hash representation of the object
29
- def to_h
30
- @attributes
31
- end
32
-
33
- # @return [Array<self>] an array representation of self
34
- def to_ary
35
- [self]
36
- end
37
-
38
- # @return [String] an easily readable representation of the object
39
- def inspect
40
- "#{super}\n" + @attributes.map { |a, v| " #{a}: #{v}" }.join("\n")
41
- end
42
-
43
- # Checks whether an attribute is supported by method_missing.
44
- # @param method_name [Symbol] the method name or attribute to check
45
- # @param include_private [Boolean] whether to also include private methods
46
- # @return [Boolean] whether the method is handled by method_missing
47
- def respond_to_missing?(method_name, include_private = false)
48
- @attributes.key?(method_name) || @attributes.key?(depredicate(method_name)) || super
49
- end
50
-
51
- # Return an attribute or raise a NoMethodError if it doesn't exist.
52
- # @param method_name [Symbol] the name of the attribute
53
- # @return [Object] the result of the attribute check
54
- def method_missing(method_name, *args, &block)
55
- return get_attribute(method_name) if @attributes.key?(method_name)
56
- return get_attribute(depredicate(method_name)) if @attributes.key?(depredicate(method_name))
57
- super
58
- end
59
-
60
- private
61
-
62
- # @abstract Lets us plug in custom code without making a mess
63
- def after_initialize; end
64
-
65
- # Remove a trailing '?' from a symbol name.
66
- # @param method_name [Symbol] the symbol to "depredicate"
67
- # @return [Symbol] the symbol but with the '?' removed
68
- def depredicate(method_name)
69
- method_name.to_s.chomp('?').to_sym
70
- end
71
-
72
- # Get an attribute, raising KeyError if not present.
73
- # @param name [Symbol] the attribute to check and get
74
- # @return [Object] the value of the attribute
75
- def get_attribute(name)
76
- @attributes.fetch(name)
77
- end
78
- end
79
- end
80
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'basic_model'
4
-
5
- module Redd
6
- module Models
7
- # The base class for lazily-initializable models.
8
- class LazyModel < BasicModel
9
- # Create a lazily initialized class.
10
- # @param client [APIClient] the client that the model uses to make requests
11
- # @param base_attributes [Hash] the already-known attributes that do not need to be looked up
12
- # @yield [client] the model's client
13
- # @yieldparam client [APIClient]
14
- # @yieldreturn [Hash] the response of "initializing" the lazy model
15
- def initialize(client, base_attributes = {}, &block)
16
- super(client, base_attributes)
17
- @lazy_loader = block
18
- @definitely_fully_loaded = false
19
- end
20
-
21
- # Force the object to make a request to reddit.
22
- # @return [self]
23
- def force_load
24
- @attributes.merge!(@lazy_loader ? @lazy_loader.call(@client) : default_loader)
25
- @definitely_fully_loaded = true
26
- after_initialize
27
- self
28
- end
29
- alias reload force_load
30
-
31
- # Convert the object to a hash, making a request to fetch additional attributes if needed.
32
- # @return [Hash]
33
- def to_h
34
- ensure_fully_loaded
35
- super
36
- end
37
-
38
- # Checks whether an attribute is supported by method_missing. Since we don't know whether an
39
- # attribute exists until we load it, we have to respond true until we load it.
40
- # @param method_name [Symbol] the method name or attribute to check
41
- # @param include_private [Boolean] whether to also include private methods
42
- # @return [Boolean] whether the method is handled by method_missing
43
- def respond_to_missing?(method_name, include_private = false)
44
- @definitely_fully_loaded ? super : true
45
- end
46
-
47
- # Return an attribute or raise a NoMethodError if it doesn't exist.
48
- # @param method_name [Symbol] the name of the attribute
49
- # @return [Object] the result of the attribute check
50
- def method_missing(method_name, *args, &block)
51
- ensure_fully_loaded unless @attributes.key?(method_name)
52
- super
53
- end
54
-
55
- private
56
-
57
- # @abstract A lazy loader to use when one is not provided.
58
- def default_loader
59
- {}
60
- end
61
-
62
- # Make sure the model is loaded at least once.
63
- def ensure_fully_loaded
64
- force_load unless @definitely_fully_loaded
65
- end
66
-
67
- # Gets the attribute and loads it if it may be available from the response.
68
- def get_attribute(name)
69
- # XXX: Replace get_attribute calls with simple method calls?
70
- ensure_fully_loaded unless @attributes.key?(name)
71
- super
72
- end
73
- end
74
- end
75
- end