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,15 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'basic_model'
4
- require_relative 'lazy_model'
3
+ require_relative 'model'
5
4
  require_relative 'messageable'
6
5
  require_relative 'searchable'
7
- require_relative '../utilities/stream'
8
6
 
9
7
  module Redd
10
8
  module Models
11
9
  # A subreddit.
12
- class Subreddit < LazyModel
10
+ class Subreddit < Model
13
11
  include Messageable
14
12
  include Searchable
15
13
 
@@ -20,72 +18,42 @@ module Redd
20
18
  content_options: :link_type,
21
19
  default_set: :allow_top,
22
20
  header_hover_text: :'header-title'
23
- }.freeze
24
-
25
- # Represents a moderator action, part of a moderation log.
26
- # @see Subreddit#log
27
- class ModAction < BasicModel; end
28
-
29
- # Create a Subreddit from its name.
30
- # @param client [APIClient] the api client to initialize the object with
31
- # @param id [String] the subreddit name
32
- # @return [Subreddit]
33
- def self.from_id(client, id)
34
- new(client, display_name: id)
35
- end
36
-
37
- # @return [Array<String>] the subreddit's wiki pages
38
- def wiki_pages
39
- @client.get("/r/#{get_attribute(:display_name)}/wiki/pages").body[:data]
40
- end
41
-
42
- # Get a wiki page by its title.
43
- # @param title [String] the page's title
44
- # @return [WikiPage]
45
- def wiki_page(title)
46
- WikiPage.new(@client, title: title, subreddit: self)
47
- end
48
-
49
- # Search a subreddit.
50
- # @param query [String] the search query
51
- # @param params [Hash] refer to {Searchable} to see search parameters
52
- # @see Searchable#search
53
- def search(query, **params)
54
- restricted_params = { restrict_to: get_attribute(:display_name) }.merge(params)
55
- super(query, restricted_params)
56
- end
21
+ }
57
22
 
58
23
  # @!group Listings
59
24
 
60
25
  # Get the appropriate listing.
61
26
  # @param sort [:hot, :new, :top, :controversial, :comments, :rising, :gilded] the type of
62
27
  # listing
63
- # @param params [Hash] a list of params to send with the request
64
- # @option params [String] :after return results after the given fullname
65
- # @option params [String] :before return results before the given fullname
66
- # @option params [Integer] :count the number of items already seen in the listing
67
- # @option params [1..100] :limit the maximum number of things to return
68
- # @option params [:hour, :day, :week, :month, :year, :all] :time the time period to consider
28
+ # @param options [Hash] a list of options to send with the request
29
+ # @option options [String] :after return results after the given fullname
30
+ # @option options [String] :before return results before the given fullname
31
+ # @option options [Integer, nil] :limit maximum number of items to return (nil for no limit)
32
+ # @option options [:hour, :day, :week, :month, :year, :all] :time the time period to consider
69
33
  # when sorting
70
34
  #
71
35
  # @note The option :time only applies to the top and controversial sorts.
72
36
  # @return [Listing<Submission, Comment>]
73
- def listing(sort, **params)
74
- params[:t] = params.delete(:time) if params.key?(:time)
75
- @client.model(:get, "/r/#{get_attribute(:display_name)}/#{sort}", params)
76
- end
77
-
78
- # @!method hot(**params)
79
- # @!method new(**params)
80
- # @!method top(**params)
81
- # @!method controversial(**params)
82
- # @!method comments(**params)
83
- # @!method rising(**params)
84
- # @!method gilded(**params)
37
+ def listing(sort, **options)
38
+ options[:t] = options.delete(:time) if options.key?(:time)
39
+ PaginatedListing.new(client, options) do |**req_options|
40
+ client.model(
41
+ :get, "/r/#{read_attribute(:display_name)}/#{sort}", options.merge(req_options)
42
+ )
43
+ end
44
+ end
45
+
46
+ # @!method hot(**options)
47
+ # @!method new(**options)
48
+ # @!method top(**options)
49
+ # @!method controversial(**options)
50
+ # @!method comments(**options)
51
+ # @!method rising(**options)
52
+ # @!method gilded(**options)
85
53
  #
86
54
  # @see #listing
87
- %i(hot new top controversial comments rising gilded).each do |sort|
88
- define_method(sort) { |**params| listing(sort, **params) }
55
+ %i[hot new top controversial comments rising gilded].each do |sort|
56
+ define_method(sort) { |**options| listing(sort, **options) }
89
57
  end
90
58
 
91
59
  # @!endgroup
@@ -102,7 +70,7 @@ module Redd
102
70
  #
103
71
  # @return [Listing<Submission, Comment>]
104
72
  def moderator_listing(type, **params)
105
- @client.model(:get, "/r/#{get_attribute(:display_name)}/about/#{type}", params)
73
+ client.model(:get, "/r/#{read_attribute(:display_name)}/about/#{type}", params)
106
74
  end
107
75
 
108
76
  # @!method reports(**params)
@@ -112,7 +80,7 @@ module Redd
112
80
  # @!method edited(**params)
113
81
  #
114
82
  # @see #moderator_listing
115
- %i(reports spam modqueue unmoderated edited).each do |type|
83
+ %i[reports spam modqueue unmoderated edited].each do |type|
116
84
  define_method(type) { |**params| moderator_listing(type, **params) }
117
85
  end
118
86
 
@@ -133,7 +101,7 @@ module Redd
133
101
  def relationship_listing(type, **params)
134
102
  # TODO: add methods to determine if a certain user was banned/muted/etc
135
103
  # TODO: return User types?
136
- user_list = @client.get("/r/#{get_attribute(:display_name)}/about/#{type}", params).body
104
+ user_list = client.get("/r/#{read_attribute(:display_name)}/about/#{type}", params).body
137
105
  user_list[:data][:children]
138
106
  end
139
107
 
@@ -145,30 +113,31 @@ module Redd
145
113
  # @!method moderators(**params)
146
114
  #
147
115
  # @see #relationship_listing
148
- %i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
116
+ %i[banned muted wikibanned contributors wikicontributors moderators].each do |type|
149
117
  define_method(type) { |**params| relationship_listing(type, **params) }
150
118
  end
151
119
 
152
120
  # @!endgroup
153
121
 
154
- # Stream newly submitted posts.
155
- def post_stream(**params, &block)
156
- params[:limit] ||= 100
157
- stream = Utilities::Stream.new do |previous|
158
- before = previous ? previous.first.name : nil
159
- listing(:new, params.merge(before: before))
160
- end
161
- block_given? ? stream.stream(&block) : stream.enum_for(:stream)
122
+ # @return [Array<String>] the subreddit's wiki pages
123
+ def wiki_pages
124
+ client.get("/r/#{read_attribute(:display_name)}/wiki/pages").body[:data]
162
125
  end
163
126
 
164
- # Stream newly submitted comments.
165
- def comment_stream(**params, &block)
166
- params[:limit] ||= 100
167
- stream = Utilities::Stream.new do |previous|
168
- before = previous ? previous.first.name : nil
169
- listing(:comments, params.merge(before: before))
170
- end
171
- block_given? ? stream.stream(&block) : stream.enum_for(:stream)
127
+ # Get a wiki page by its title.
128
+ # @param title [String] the page's title
129
+ # @return [WikiPage]
130
+ def wiki_page(title)
131
+ WikiPage.new(client, title: title, subreddit: self)
132
+ end
133
+
134
+ # Search a subreddit.
135
+ # @param query [String] the search query
136
+ # @param params [Hash] refer to {Searchable} to see search parameters
137
+ # @see Searchable#search
138
+ def search(query, **params)
139
+ restricted_params = { restrict_to: read_attribute(:display_name) }.merge(params)
140
+ super(query, restricted_params)
172
141
  end
173
142
 
174
143
  # Submit a link or a text post to the subreddit.
@@ -183,13 +152,13 @@ module Redd
183
152
  # @return [Submission] The returned object (url, id and name)
184
153
  def submit(title, text: nil, url: nil, resubmit: false, sendreplies: true)
185
154
  params = {
186
- title: title, sr: get_attribute(:display_name),
155
+ title: title, sr: read_attribute(:display_name),
187
156
  resubmit: resubmit, sendreplies: sendreplies
188
157
  }
189
158
  params[:kind] = url ? 'link' : 'self'
190
159
  params[:url] = url if url
191
160
  params[:text] = text if text
192
- Submission.new(@client, @client.post('/api/submit', params).body[:json][:data])
161
+ Submission.new(client, client.post('/api/submit', params).body[:json][:data])
193
162
  end
194
163
 
195
164
  # Compose a message to the moderators of a subreddit.
@@ -198,7 +167,7 @@ module Redd
198
167
  # @param text [String] the message text
199
168
  # @param from [Subreddit, nil] the subreddit to send the message on behalf of
200
169
  def send_message(subject:, text:, from: nil)
201
- super(to: "/r/#{get_attribute(:display_name)}", subject: subject, text: text, from: from)
170
+ super(to: "/r/#{read_attribute(:display_name)}", subject: subject, text: text, from: from)
202
171
  end
203
172
 
204
173
  # Set the flair for a link or a user for this subreddit.
@@ -209,7 +178,7 @@ module Redd
209
178
  key = thing.is_a?(User) ? :name : :link
210
179
  params = { :text => text, key => thing.name }
211
180
  params[:css_class] = css_class if css_class
212
- @client.post("/r/#{get_attribute(:display_name)}/api/flair", params)
181
+ client.post("/r/#{read_attribute(:display_name)}/api/flair", params)
213
182
  end
214
183
 
215
184
  # Get a listing of all user flairs.
@@ -222,8 +191,8 @@ module Redd
222
191
  #
223
192
  # @return [Listing<Hash<Symbol, String>>]
224
193
  def flair_listing(**params)
225
- res = @client.get("/r/#{get_attribute(:display_name)}/api/flairlist", params).body
226
- Listing.new(@client, children: res[:users], before: res[:prev], after: res[:next])
194
+ res = client.get("/r/#{read_attribute(:display_name)}/api/flairlist", params).body
195
+ Listing.new(client, children: res[:users], before: res[:prev], after: res[:next])
227
196
  end
228
197
 
229
198
  # Get the user's flair data.
@@ -240,7 +209,7 @@ module Redd
240
209
  # @param thing [User, String] a User from which to remove flair
241
210
  def delete_flair(user)
242
211
  name = user.is_a?(User) ? user.name : user
243
- @client.post("/r/#{get_attribute(:display_name)}/api/deleteflair", name: name)
212
+ client.post("/r/#{read_attribute(:display_name)}/api/deleteflair", name: name)
244
213
  end
245
214
 
246
215
  # Set a Submission's or User's flair based on a flair template id.
@@ -250,14 +219,14 @@ module Redd
250
219
  def set_flair_template(thing, template_id, text: nil)
251
220
  key = thing.is_a?(User) ? :name : :link
252
221
  params = { key => thing.name, flair_template_id: template_id, text: text }
253
- @client.post("/r/#{get_attribute(:display_name)}/api/selectflair", params)
222
+ client.post("/r/#{read_attribute(:display_name)}/api/selectflair", params)
254
223
  end
255
224
 
256
225
  # Add the subreddit to the user's subscribed subreddits.
257
226
  def subscribe(action: :sub, skip_initial_defaults: false)
258
- @client.post(
227
+ client.post(
259
228
  '/api/subscribe',
260
- sr_name: get_attribute(:display_name),
229
+ sr_name: read_attribute(:display_name),
261
230
  action: action,
262
231
  skip_initial_defaults: skip_initial_defaults
263
232
  )
@@ -271,9 +240,9 @@ module Redd
271
240
  # Get the subreddit's CSS.
272
241
  # @return [String, nil] the stylesheet or nil if no stylesheet exists
273
242
  def stylesheet
274
- url = @client.get("/r/#{get_attribute(:display_name)}/stylesheet").headers['location']
243
+ url = client.get("/r/#{read_attribute(:display_name)}/stylesheet").headers['location']
275
244
  HTTP.get(url).body.to_s
276
- rescue Redd::NotFound
245
+ rescue Errors::NotFound
277
246
  nil
278
247
  end
279
248
 
@@ -283,12 +252,12 @@ module Redd
283
252
  def update_stylesheet(text, reason: nil)
284
253
  params = { op: 'save', stylesheet_contents: text }
285
254
  params[:reason] = reason if reason
286
- @client.post("/r/#{get_attribute(:display_name)}/api/subreddit_stylesheet", params)
255
+ client.post("/r/#{read_attribute(:display_name)}/api/subreddit_stylesheet", params)
287
256
  end
288
257
 
289
258
  # @return [Hash] the subreddit's settings
290
259
  def settings
291
- @client.get("/r/#{get_attribute(:display_name)}/about/edit").body[:data]
260
+ client.get("/r/#{read_attribute(:display_name)}/about/edit").body[:data]
292
261
  end
293
262
 
294
263
  # Modify the subreddit's settings.
@@ -296,9 +265,9 @@ module Redd
296
265
  # @see https://www.reddit.com/dev/api#POST_api_site_admin
297
266
  def modify_settings(**params)
298
267
  full_params = settings.merge(params)
299
- full_params[:sr] = get_attribute(:name)
268
+ full_params[:sr] = read_attribute(:name)
300
269
  SETTINGS_MAP.each { |src, dest| full_params[dest] = full_params.delete(src) }
301
- @client.post('/api/site_admin', full_params)
270
+ client.post('/api/site_admin', full_params)
302
271
  end
303
272
 
304
273
  # Get the moderation log.
@@ -311,7 +280,7 @@ module Redd
311
280
  #
312
281
  # @return [Listing<ModAction>]
313
282
  def mod_log(**params)
314
- @client.model(:get, "/r/#{get_attribute(:display_name)}/about/log", params)
283
+ client.model(:get, "/r/#{read_attribute(:display_name)}/about/log", params)
315
284
  end
316
285
 
317
286
  # Invite a user to moderate this subreddit.
@@ -329,7 +298,7 @@ module Redd
329
298
 
330
299
  # Accept an invite to become a moderator of this subreddit.
331
300
  def accept_moderator_invite
332
- @client.post("/r/#{get_attribute(:display_name)}/api/accept_moderator_invite")
301
+ client.post("/r/#{read_attribute(:display_name)}/api/accept_moderator_invite")
333
302
  end
334
303
 
335
304
  # Dethrone a moderator.
@@ -340,7 +309,7 @@ module Redd
340
309
 
341
310
  # Leave from being a moderator on a subreddit.
342
311
  def leave_moderator
343
- @client.post('/api/leavemoderator', id: get_attribute(:name))
312
+ client.post('/api/leavemoderator', id: read_attribute(:name))
344
313
  end
345
314
 
346
315
  # Add a contributor to the subreddit.
@@ -357,7 +326,7 @@ module Redd
357
326
 
358
327
  # Leave from being a contributor on a subreddit.
359
328
  def leave_contributor
360
- @client.post('/api/leavecontributor', id: get_attribute(:name))
329
+ client.post('/api/leavecontributor', id: read_attribute(:name))
361
330
  end
362
331
 
363
332
  # Ban a user from a subreddit.
@@ -415,21 +384,279 @@ module Redd
415
384
  file_data = HTTP::FormData::File.new(file)
416
385
  params = { img_type: image_type, upload_type: upload_type, file: file_data }
417
386
  params[:name] = image_name if upload_type.to_s == 'img'
418
- @client.post("/r/#{display_name}/api/upload_sr_img", params).body[:img_src]
387
+ client.post("/r/#{read_attribute(:display_name)}/api/upload_sr_img", params).body[:img_src]
388
+ end
389
+
390
+ # Delete a subreddit-specific image.
391
+ # @param upload_type ['img', 'header', 'icon', 'banner'] the image to delete
392
+ # @param image_name [String] the image name (if upload_type is 'img')
393
+ def delete_image(upload_type:, image_name: nil)
394
+ unless %w[img header icon banner].include?(upload_type)
395
+ raise ArgumentError, 'unknown upload_type'
396
+ end
397
+ params = {}
398
+ params[:name] = image_name if upload_type.to_s == 'img'
399
+ client.post("/r/#{read_attribute(:display_name)}/api/delete_sr_#{upload_type}", params)
419
400
  end
420
401
 
402
+ # @!attribute [r] display_name
403
+ # @return [String] the subreddit's name
404
+ property :display_name, :required
405
+
406
+ # @!attribute [r] id
407
+ # @return [String] the subreddit's t5_ id.
408
+ property :id
409
+
410
+ # @!attribute [r] title
411
+ # @return [String] the subreddit's page title text.
412
+ property :title
413
+
414
+ # @!attribute [r] user_is_contributor?
415
+ # @return [Boolean] whether the logged-in user is the subreddit's contributor
416
+ property :user_is_contributor?, from: :user_is_contributor
417
+
418
+ # @!attribute [r] banner_image
419
+ # @return [String] the url to the subreddit's banner image
420
+ property :banner_image, from: :banner_img
421
+
422
+ # @!attribute [r] banner_size
423
+ # @return [Array<Integer>] the banner dimensions
424
+ property :banner_size
425
+
426
+ # @!attribute [r] user_flair_text
427
+ # @return [String] the logged-in user's flair text
428
+ property :user_flair_text
429
+
430
+ # @!attribute [r] user_flair_css_class
431
+ # @return [String] the css class for the user's flair
432
+ property :user_flair_css_class
433
+
434
+ # @!attribute [r] user_is_banned
435
+ # @return [Boolean] whether the logged-in user is banned from this subreddit
436
+ property :user_is_banned?, from: :user_is_banned
437
+
438
+ # @!attribute [r] user_is_moderator?
439
+ # @return [Boolean] whether the logged-in user is a moderator of the subreddit
440
+ property :user_is_moderator?, from: :user_is_moderator
441
+
442
+ # @!attribute [r] user_is_muted?
443
+ # @return [Boolean] whether the logged-in user is muted from the subreddit
444
+ property :user_is_muted?, from: :user_is_muted
445
+
446
+ # @!attribute [r] user_is_subscriber
447
+ # @return [Boolean] whether the logged-in user is a subscriber to the subreddit
448
+ property :user_is_subscriber?, from: :user_is_subscriber
449
+
450
+ # @!attribute [r] wiki_enabled?
451
+ # @return [Boolean] whether the wiki is enabled for this subreddit
452
+ property :wiki_enabled?, from: :wiki_enabled
453
+
454
+ # @!attribute [r] show_media?
455
+ # @return [Boolean] whether media is shown
456
+ property :show_media?, from: :show_media
457
+
458
+ # @!attribute [r] description
459
+ # @return [String] the subreddit description
460
+ property :description
461
+
462
+ # @!attribute [r] description_html
463
+ # @return [String] the html-rendered version of the subreddit description
464
+ property :description_html
465
+
466
+ # @!attribute [r] submit_text
467
+ # @return [String] the submit text
468
+ property :submit_text
469
+
470
+ # @!attribute [r] submit_text_html
471
+ # @return [String] the submit text html
472
+ property :submit_text_html
473
+
474
+ # @!attribute [r] can_set_flair?
475
+ # @return [Boolean] whether the user can set the flair in the subreddit
476
+ property :can_set_flair?, from: :user_can_flair_in_sr
477
+
478
+ # @!attribute [r] header_img
479
+ # @return [String] the url to the header image
480
+ property :header_image, from: :header_img
481
+
482
+ # @!attribute [r] header_size
483
+ # @return [Array<Integer>] the dimensions of the header image
484
+ property :header_size
485
+
486
+ # @!attribute [r] collapse_deleted_comments?
487
+ # @return [Boolean] whether deleted comments are collapsed
488
+ property :collapse_deleted_comments?, from: :collapse_deleted_comments
489
+
490
+ # @!attribute [r] user_has_favorited?
491
+ # @return [Boolean] whether the user has favourited the subreddit
492
+ property :user_has_favorited?, from: :user_has_favorited
493
+
494
+ # @!attribute [r] public_description
495
+ # @return [String] the public description
496
+ property :public_description
497
+
498
+ # @!attribute [r] public_description_html
499
+ # @return [String] the html-rendered version of the public description
500
+ property :public_description_html
501
+
502
+ # @!attribute [r] over_18?
503
+ # @return [Boolean] whether the user is marked as over 18
504
+ property :over_18?, from: :over18
505
+
506
+ # @!attribute [r] spoilers_enabled?
507
+ # @return [Boolean] whether the subreddit has spoilers enabled
508
+ property :spoilers_enabled?, from: :spoilers_enabled
509
+
510
+ # @!attribute [r] icon_size
511
+ # @return [Array<Integer>] the subreddit icon size
512
+ property :icon_size
513
+
514
+ # @!attribute [r] audience_target
515
+ # @return [String] no clue what this means
516
+ property :audience_target
517
+
518
+ # @!attribute [r] suggested_comment_sort
519
+ # @return [String] the suggested comment sort
520
+ property :suggested_comment_sort
521
+
522
+ # @!attribute [r] active_user_count
523
+ # @return [Integer] the number of active users
524
+ property :active_user_count
525
+
526
+ # @!attribute [r] accounts_active
527
+ # @return [Integer] the number of active accounts
528
+ property :accounts_active
529
+
530
+ # @!attribute [r] subscribers
531
+ # @return [Integer] the subreddit's subscriber count
532
+ property :subscribers
533
+
534
+ # @!attribute [r] icon_image
535
+ # @return [String] the url to the icon image
536
+ property :icon_image, from: :icon_img
537
+
538
+ # @!attribute [r] header_title
539
+ # @return [String] the header's "title" attribute (i.e. mouseover text)
540
+ property :header_title
541
+
542
+ # @!attribute [r] display_name_prefixed
543
+ # @return [String] the display name, prefixed with a "r/".
544
+ # @deprecated not really deprecated, but prefer just using the display_name directly
545
+ property :display_name_prefixed, default: ->() { "r/#{read_attribute(:display_name)}" }
546
+
547
+ # @!attribute [r] submit_link_label
548
+ # @return [String] the label text on the submit link button
549
+ property :submit_link_label
550
+
551
+ # @!attribute [r] submit_text_label
552
+ # @return [String] the label text on the submit text button
553
+ property :submit_text_label
554
+
555
+ # @!attribute [r] public_traffic
556
+ # @return [Boolean] whether the traffic page is public
557
+ property :public_traffic?, from: :public_traffic
558
+
559
+ # @!attribute [r] key_color
560
+ # @return [String] a hex color code, not sure what this does
561
+ property :key_color
562
+
563
+ # @!attribute [r] user_flair_visible?
564
+ # @return [Boolean] whether the user's flair is shown to others
565
+ property :user_flair_visible?, from: :user_sr_flair_enabled
566
+
567
+ # @!attribute [r] user_flair_enabled?
568
+ # @return [Boolean] whether the subreddit allows setting user flairs
569
+ property :user_flair_enabled?, from: :user_flair_enabled_in_sr
570
+
571
+ # @!attribute [r] language
572
+ # @return [String] the subreddit's language code
573
+ property :language, from: :lang
574
+
575
+ # @!attribute [r] enrolled_in_new_modmail?
576
+ # @return [Boolean] whether the subreddit is enrolled in the new modmail
577
+ property :enrolled_in_new_modmail?, from: :is_enrolled_in_new_modmail
578
+
579
+ # @!attribute [r] whitelist_status
580
+ # @return [String] not sure what this does, something to do with ads?
581
+ property :whitelist_status
582
+
583
+ # @!attribute [r] url
584
+ # @return [String] the subreddit's **relative** url (e.g. /r/Redd/)
585
+ property :url, default: ->() { "/r/#{read_attribute(:display_name)}/" }
586
+
587
+ # @!attribute [r] quarantined?
588
+ # @return [Boolean] whether the subreddit is quarantined
589
+ property :quarantined?, from: :quarantine
590
+
591
+ # @!attribute [r] hide_ads?
592
+ # @return [Boolean] whether ads are hidden?
593
+ property :hide_ads?, from: :hide_ads
594
+
595
+ # @!attribute [r] created_at
596
+ # @return [Time] the time the subreddit was created
597
+ property :created_at, from: :created_utc, with: ->(t) { Time.at(t) }
598
+
599
+ # @!attribute [r] accounts_active_is_fuzzed
600
+ # @return [Boolean] whether active accounts is fuzzed
601
+ property :accounts_active_is_fuzzed?, from: :accounts_active_is_fuzzed
602
+
603
+ # @!attribute [r] advertiser_category
604
+ # @return [String] the advertiser category
605
+ property :advertiser_category
606
+
607
+ # @!attribute [r] subreddit_theme_enabled?
608
+ # @return [Boolean] whether the subreddit theme is enabled
609
+ property :subreddit_theme_enabled?, from: :user_sr_theme_enabled
610
+
611
+ # @!attribute [r] link_flair_enabled
612
+ # @return [Boolean] whether link flairs are enabled
613
+ property :link_flair_enabled?, from: :link_flair_enabled
614
+
615
+ # @!attribute [r] allow_images?
616
+ # @return [Boolean] whether images are allowed
617
+ property :allow_images?, from: :allow_images
618
+
619
+ # @!attribute [r] show_media_preview
620
+ # @return [Boolean] whether media previews are shown
621
+ property :show_media_preview?, from: :show_media_preview
622
+
623
+ # @!attribute [r] comment_score_hide_mins
624
+ # @return [Integer] the number of minutes the comment score is hidden
625
+ property :comment_score_hide_mins
626
+
627
+ # @!attribute [r] subreddit_type
628
+ # @return [String] whether it's a public, private, or gold-restricted subreddit
629
+ property :subreddit_type
630
+
631
+ # @!attribute [r] submission_type
632
+ # @return [String] the allowed submission type (?)
633
+ property :submission_type
634
+
421
635
  private
422
636
 
423
- def default_loader
424
- @client.get("/r/#{@attributes.fetch(:display_name)}/about").body[:data]
637
+ def lazer_reload
638
+ fully_loaded!
639
+ self[:name] ? load_from_fullname : load_from_display_name
640
+ end
641
+
642
+ # Return the attributes using the display_name (best option).
643
+ def load_from_display_name
644
+ client.get("/r/#{read_attribute(:display_name)}/about").body[:data]
645
+ end
646
+
647
+ # Load the attributes using the subreddit fullname (not so best option).
648
+ def load_from_fullname
649
+ response = client.get('/api/info', id: read_attribute(:name))
650
+ raise Errors::NotFound.new(response) if response.body[:data][:children].empty?
651
+ response.body[:data][:children][0][:data]
425
652
  end
426
653
 
427
654
  def add_relationship(**params)
428
- @client.post("/r/#{get_attribute(:display_name)}/api/friend", params)
655
+ client.post("/r/#{read_attribute(:display_name)}/api/friend", params)
429
656
  end
430
657
 
431
658
  def remove_relationship(**params)
432
- @client.post("/r/#{get_attribute(:display_name)}/api/unfriend", params)
659
+ client.post("/r/#{read_attribute(:display_name)}/api/unfriend", params)
433
660
  end
434
661
  end
435
662
  end