Class: Redd::Models::Subreddit

Inherits:
LazyModel show all
Includes:
Messageable, Searchable
Defined in:
lib/redd/models/subreddit.rb

Overview

A subreddit.

Defined Under Namespace

Classes: ModAction

Constant Summary collapse

SETTINGS_MAP =

A mapping from keys returned by #settings to keys required by #modify_settings

{
  subreddit_type: :type,
  language: :lang,
  content_options: :link_type,
  default_set: :allow_top,
  header_hover_text: :'header-title'
}.freeze

Instance Attribute Summary

Attributes inherited from BasicModel

#client

Listings collapse

Moderator Listings collapse

Relationship Listings collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from LazyModel

#force_load, #initialize, #method_missing, #respond_to_missing?, #to_h

Methods inherited from BasicModel

#initialize, #inspect, #method_missing, #respond_to_missing?, #to_ary, #to_h

Constructor Details

This class inherits a constructor from Redd::Models::LazyModel

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Redd::Models::LazyModel

Class Method Details

.from_id(client, id) ⇒ Subreddit

Create a Subreddit from its name.

Parameters:

  • client (APIClient)

    the api client to initialize the object with

  • id (String)

    the subreddit name

Returns:


33
34
35
# File 'lib/redd/models/subreddit.rb', line 33

def self.from_id(client, id)
  new(client, display_name: id)
end

Instance Method Details

#accept_moderator_inviteObject

Accept an invite to become a moderator of this subreddit.


331
332
333
# File 'lib/redd/models/subreddit.rb', line 331

def accept_moderator_invite
  @client.post("/r/#{get_attribute(:display_name)}/api/accept_moderator_invite")
end

#add_contributor(user) ⇒ Object

Add a contributor to the subreddit.

Parameters:

  • user (User)

    the user to add


348
349
350
# File 'lib/redd/models/subreddit.rb', line 348

def add_contributor(user)
  add_relationship(type: 'contributor', name: user.name)
end

#add_wiki_contributor(user) ⇒ Object

Allow a user to contribute to the wiki.

Parameters:

  • user (User)

    the user to add


382
383
384
# File 'lib/redd/models/subreddit.rb', line 382

def add_wiki_contributor(user)
  add_relationship(type: 'wikicontributor', name: user.name)
end

#ban(user, **params) ⇒ Object

Ban a user from a subreddit.

Parameters:

  • user (User)

    the user to ban

  • params (Hash)

    additional options to supply with the request

Options Hash (**params):

  • :ban_reason (String)

    the reason for the ban

  • :ban_message (String)

    a message sent to the banned user

  • :note (String)

    a note that only moderators can see

  • :duration (Integer)

    the number of days to ban the user (if temporary)


370
371
372
# File 'lib/redd/models/subreddit.rb', line 370

def ban(user, **params)
  add_relationship(type: 'banned', name: user.name, **params)
end

#ban_wiki_contributor(user, **params) ⇒ Object

Ban a user from contributing to the wiki.

Parameters:

  • user (User)

    the user to ban

  • params (Hash)

    additional options to supply with the request

Options Hash (**params):

  • :ban_reason (String)

    the reason for the ban (not sure this matters)

  • :note (String)

    a note that only moderators can see

  • :duration (Integer)

    the number of days to ban the user (if temporary)


398
399
400
# File 'lib/redd/models/subreddit.rb', line 398

def ban_wiki_contributor(user, **params)
  add_relationship(type: 'wikibanned', name: user.name, **params)
end

#banned(**params) ⇒ Object


148
149
150
# File 'lib/redd/models/subreddit.rb', line 148

%i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
  define_method(type) { |**params| relationship_listing(type, **params) }
end

#comment_stream(**params, &block) ⇒ Object

Stream newly submitted comments.


165
166
167
168
169
170
171
172
# File 'lib/redd/models/subreddit.rb', line 165

def comment_stream(**params, &block)
  params[:limit] ||= 100
  stream = Utilities::Stream.new do |previous|
    before = previous ? previous.first.name : nil
    listing(:comments, params.merge(before: before))
  end
  block_given? ? stream.stream(&block) : stream.enum_for(:stream)
end

#comments(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#contributors(**params) ⇒ Object


148
149
150
# File 'lib/redd/models/subreddit.rb', line 148

%i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
  define_method(type) { |**params| relationship_listing(type, **params) }
end

#controversial(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#delete_flair(user) ⇒ Object

Remove the flair from a user

Parameters:

  • thing (User, String)

    a User from which to remove flair


241
242
243
244
# File 'lib/redd/models/subreddit.rb', line 241

def delete_flair(user)
  name = user.is_a?(User) ? user.name : user
  @client.post("/r/#{get_attribute(:display_name)}/api/deleteflair", name: name)
end

#edited(**params) ⇒ Object

See Also:


115
116
117
# File 'lib/redd/models/subreddit.rb', line 115

%i(reports spam modqueue unmoderated edited).each do |type|
  define_method(type) { |**params| moderator_listing(type, **params) }
end

#flair_listing(**params) ⇒ Listing<Hash<Symbol, String>>

Get a listing of all user flairs.

Parameters:

  • params (Hash)

    a list of params to send with the request

Options Hash (**params):

  • :after (String)

    return results after the given fullname

  • :before (String)

    return results before the given fullname

  • :count (Integer)

    the number of items already seen in the listing

  • :name (String)

    prefer #get_flair

  • :only (:links, :comments)

    the type of objects required

Returns:


224
225
226
227
# File 'lib/redd/models/subreddit.rb', line 224

def flair_listing(**params)
  res = @client.get("/r/#{get_attribute(:display_name)}/api/flairlist", params).body
  Listing.new(@client, children: res[:users], before: res[:prev], after: res[:next])
end

#get_flair(user) ⇒ Hash?

Get the user's flair data.

Parameters:

  • user (User)

    the user whose flair to fetch

Returns:

  • (Hash, nil)

232
233
234
235
236
237
# File 'lib/redd/models/subreddit.rb', line 232

def get_flair(user)
  # We have to do this because reddit returns all flairs if given a nonexistent user
  flair = flair_listing(name: user.name).first
  return flair if flair && flair[:user].casecmp(user.name).zero?
  nil
end

#gilded(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#hot(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#invite_moderator(user, permissions: '+all') ⇒ Object

Invite a user to moderate this subreddit.

Parameters:

  • user (User)

    the user to invite

  • permissions (String) (defaults to: '+all')

    the permission string to invite the user with


320
321
322
# File 'lib/redd/models/subreddit.rb', line 320

def invite_moderator(user, permissions: '+all')
  add_relationship(type: 'moderator_invite', name: user.name, permissions: permissions)
end

#leave_contributorObject

Leave from being a contributor on a subreddit.


359
360
361
# File 'lib/redd/models/subreddit.rb', line 359

def leave_contributor
  @client.post('/api/leavecontributor', id: get_attribute(:name))
end

#leave_moderatorObject

Leave from being a moderator on a subreddit.


342
343
344
# File 'lib/redd/models/subreddit.rb', line 342

def leave_moderator
  @client.post('/api/leavemoderator', id: get_attribute(:name))
end

#listing(sort, **params) ⇒ Listing<Submission, Comment>

Note:

The option :time only applies to the top and controversial sorts.

Get the appropriate listing.

Parameters:

  • sort (:hot, :new, :top, :controversial, :comments, :rising, :gilded)

    the type of listing

  • params (Hash)

    a list of params to send with the request

Options Hash (**params):

  • :after (String)

    return results after the given fullname

  • :before (String)

    return results before the given fullname

  • :count (Integer)

    the number of items already seen in the listing

  • :limit (1..100)

    the maximum number of things to return

  • :time (:hour, :day, :week, :month, :year, :all)

    the time period to consider when sorting

Returns:


73
74
75
76
# File 'lib/redd/models/subreddit.rb', line 73

def listing(sort, **params)
  params[:t] = params.delete(:time) if params.key?(:time)
  @client.model(:get, "/r/#{get_attribute(:display_name)}/#{sort}", params)
end

#mod_log(**params) ⇒ Listing<ModAction>

Get the moderation log.

Parameters:

  • params (Hash)

    a list of params to send with the request

Options Hash (**params):

  • :after (String)

    return results after the given fullname

  • :before (String)

    return results before the given fullname

  • :count (Integer)

    the number of items already seen in the listing

  • :limit (1..100)

    the maximum number of things to return

  • :type (String)

    filter events to a specific type

Returns:


313
314
315
# File 'lib/redd/models/subreddit.rb', line 313

def mod_log(**params)
  @client.model(:get, "/r/#{get_attribute(:display_name)}/about/log", params)
end

#moderator_listing(type, **params) ⇒ Listing<Submission, Comment>

Get the appropriate moderator listing.

Parameters:

  • type (:reports, :spam, :modqueue, :unmoderated, :edited)

    the type of listing

  • params (Hash)

    a list of params to send with the request

Options Hash (**params):

  • :after (String)

    return results after the given fullname

  • :before (String)

    return results before the given fullname

  • :count (Integer)

    the number of items already seen in the listing

  • :limit (1..100)

    the maximum number of things to return

  • :only (:links, :comments)

    the type of objects required

Returns:


104
105
106
# File 'lib/redd/models/subreddit.rb', line 104

def moderator_listing(type, **params)
  @client.model(:get, "/r/#{get_attribute(:display_name)}/about/#{type}", params)
end

#moderators(**params) ⇒ Object


148
149
150
# File 'lib/redd/models/subreddit.rb', line 148

%i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
  define_method(type) { |**params| relationship_listing(type, **params) }
end

#modify_settings(**params) ⇒ Object

Modify the subreddit's settings.

Parameters:

  • params (Hash)

    the settings to change

See Also:


297
298
299
300
301
302
# File 'lib/redd/models/subreddit.rb', line 297

def modify_settings(**params)
  full_params = settings.merge(params)
  full_params[:sr] = get_attribute(:name)
  SETTINGS_MAP.each { |src, dest| full_params[dest] = full_params.delete(src) }
  @client.post('/api/site_admin', full_params)
end

#modqueue(**params) ⇒ Object

See Also:


115
116
117
# File 'lib/redd/models/subreddit.rb', line 115

%i(reports spam modqueue unmoderated edited).each do |type|
  define_method(type) { |**params| moderator_listing(type, **params) }
end

#muted(**params) ⇒ Object


148
149
150
# File 'lib/redd/models/subreddit.rb', line 148

%i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
  define_method(type) { |**params| relationship_listing(type, **params) }
end

#new(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#post_stream(**params, &block) ⇒ Object

Stream newly submitted posts.


155
156
157
158
159
160
161
162
# File 'lib/redd/models/subreddit.rb', line 155

def post_stream(**params, &block)
  params[:limit] ||= 100
  stream = Utilities::Stream.new do |previous|
    before = previous ? previous.first.name : nil
    listing(:new, params.merge(before: before))
  end
  block_given? ? stream.stream(&block) : stream.enum_for(:stream)
end

#relationship_listing(type, **params) ⇒ Array<Hash>

Get the appropriate relationship listing.

Parameters:

  • type (:banned, :muted, :wikibanned, :contributors, :wikicontributors, :moderators)

    the type of listing

  • params (Hash)

    a list of params to send with the request

Options Hash (**params):

  • :after (String)

    return results after the given fullname

  • :before (String)

    return results before the given fullname

  • :count (Integer)

    the number of items already seen in the listing

  • :limit (1..100)

    the maximum number of things to return

  • :user (String)

    find a specific user

Returns:

  • (Array<Hash>)

133
134
135
136
137
138
# File 'lib/redd/models/subreddit.rb', line 133

def relationship_listing(type, **params)
  # TODO: add methods to determine if a certain user was banned/muted/etc
  # TODO: return User types?
  user_list = @client.get("/r/#{get_attribute(:display_name)}/about/#{type}", params).body
  user_list[:data][:children]
end

#remove_contributor(user) ⇒ Object

Remove a contributor from the subreddit.

Parameters:

  • user (User)

    the user to remove


354
355
356
# File 'lib/redd/models/subreddit.rb', line 354

def remove_contributor(user)
  remove_relationship(type: 'contributor', name: user.name)
end

#remove_moderator(user) ⇒ Object

Dethrone a moderator.

Parameters:

  • user (User)

    the user to remove


337
338
339
# File 'lib/redd/models/subreddit.rb', line 337

def remove_moderator(user)
  remove_relationship(type: 'moderator', name: user.name)
end

#remove_wiki_contributor(user) ⇒ Object

No longer allow a user to contribute to the wiki.

Parameters:

  • user (User)

    the user to remove


388
389
390
# File 'lib/redd/models/subreddit.rb', line 388

def remove_wiki_contributor(user)
  remove_relationship(type: 'wikicontributor', name: user.name)
end

#reports(**params) ⇒ Object

See Also:


115
116
117
# File 'lib/redd/models/subreddit.rb', line 115

%i(reports spam modqueue unmoderated edited).each do |type|
  define_method(type) { |**params| moderator_listing(type, **params) }
end

#rising(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#search(query, **params) ⇒ Object

Search a subreddit.

Parameters:

See Also:


53
54
55
56
# File 'lib/redd/models/subreddit.rb', line 53

def search(query, **params)
  restricted_params = { restrict_to: get_attribute(:display_name) }.merge(params)
  super(query, restricted_params)
end

#send_message(subject:, text:, from: nil) ⇒ Object

Compose a message to the moderators of a subreddit.

Parameters:

  • subject (String)

    the subject of the message

  • text (String)

    the message text

  • from (Subreddit, nil) (defaults to: nil)

    the subreddit to send the message on behalf of


200
201
202
# File 'lib/redd/models/subreddit.rb', line 200

def send_message(subject:, text:, from: nil)
  super(to: "/r/#{get_attribute(:display_name)}", subject: subject, text: text, from: from)
end

#set_flair(thing, text, css_class: nil) ⇒ Object

Set the flair for a link or a user for this subreddit.

Parameters:

  • thing (User, Submission)

    the object whose flair to edit

  • text (String)

    a string no longer than 64 characters

  • css_class (String) (defaults to: nil)

    the css class to assign to the flair


208
209
210
211
212
213
# File 'lib/redd/models/subreddit.rb', line 208

def set_flair(thing, text, css_class: nil)
  key = thing.is_a?(User) ? :name : :link
  params = { :text => text, key => thing.name }
  params[:css_class] = css_class if css_class
  @client.post("/r/#{get_attribute(:display_name)}/api/flair", params)
end

#set_flair_template(thing, template_id, text: nil) ⇒ Object

Set a Submission's or User's flair based on a flair template id.

Parameters:

  • thing (User, Submission)

    an object to assign a template to

  • template_id (String)

    the UUID of the flair template to assign

  • text (String) (defaults to: nil)

    optional text for the flair


250
251
252
253
254
# File 'lib/redd/models/subreddit.rb', line 250

def set_flair_template(thing, template_id, text: nil)
  key = thing.is_a?(User) ? :name : :link
  params = { key => thing.name, flair_template_id: template_id, text: text }
  @client.post("/r/#{get_attribute(:display_name)}/api/selectflair", params)
end

#settingsHash

Returns the subreddit's settings.

Returns:

  • (Hash)

    the subreddit's settings


290
291
292
# File 'lib/redd/models/subreddit.rb', line 290

def settings
  @client.get("/r/#{get_attribute(:display_name)}/about/edit").body[:data]
end

#spam(**params) ⇒ Object

See Also:


115
116
117
# File 'lib/redd/models/subreddit.rb', line 115

%i(reports spam modqueue unmoderated edited).each do |type|
  define_method(type) { |**params| moderator_listing(type, **params) }
end

#stylesheetString?

Get the subreddit's CSS.

Returns:

  • (String, nil)

    the stylesheet or nil if no stylesheet exists


273
274
275
276
277
278
# File 'lib/redd/models/subreddit.rb', line 273

def stylesheet
  url = @client.get("/r/#{get_attribute(:display_name)}/stylesheet").headers['location']
  HTTP.get(url).body.to_s
rescue Redd::NotFound
  nil
end

#submit(title, text: nil, url: nil, resubmit: false, sendreplies: true) ⇒ Submission

Note:

If both text and url are provided, url takes precedence.

Submit a link or a text post to the subreddit.

Parameters:

  • title (String)

    the title of the submission

  • text (String) (defaults to: nil)

    the text of the self-post

  • url (String) (defaults to: nil)

    the URL of the link

  • resubmit (Boolean) (defaults to: false)

    whether to post a link to the subreddit despite it having been posted there before (you monster)

  • sendreplies (Boolean) (defaults to: true)

    whether to send the replies to your inbox

Returns:

  • (Submission)

    The returned object (url, id and name)


184
185
186
187
188
189
190
191
192
193
# File 'lib/redd/models/subreddit.rb', line 184

def submit(title, text: nil, url: nil, resubmit: false, sendreplies: true)
  params = {
    title: title, sr: get_attribute(:display_name),
    resubmit: resubmit, sendreplies: sendreplies
  }
  params[:kind] = url ? 'link' : 'self'
  params[:url]  = url  if url
  params[:text] = text if text
  Submission.new(@client, @client.post('/api/submit', params).body[:json][:data])
end

#subscribe(action: :sub, skip_initial_defaults: false) ⇒ Object

Add the subreddit to the user's subscribed subreddits.


257
258
259
260
261
262
263
264
# File 'lib/redd/models/subreddit.rb', line 257

def subscribe(action: :sub, skip_initial_defaults: false)
  @client.post(
    '/api/subscribe',
    sr_name: get_attribute(:display_name),
    action: action,
    skip_initial_defaults: skip_initial_defaults
  )
end

#top(**params) ⇒ Object

See Also:


87
88
89
# File 'lib/redd/models/subreddit.rb', line 87

%i(hot new top controversial comments rising gilded).each do |sort|
  define_method(sort) { |**params| listing(sort, **params) }
end

#unban(user) ⇒ Object

Remove a ban on a user.

Parameters:

  • user (User)

    the user to unban


376
377
378
# File 'lib/redd/models/subreddit.rb', line 376

def unban(user)
  remove_relationship(type: 'banned', name: user.name)
end

#unban_wiki_contributor(user) ⇒ Object

No longer ban a user from contributing to the wiki.

Parameters:

  • user (User)

    the user to unban


404
405
406
# File 'lib/redd/models/subreddit.rb', line 404

def unban_wiki_contributor(user)
  remove_relationship(type: 'wikibanned', name: user.name)
end

#uninvite_moderator(user) ⇒ Object

Take back a moderator request.

Parameters:

  • user (User)

    the requested user


326
327
328
# File 'lib/redd/models/subreddit.rb', line 326

def uninvite_moderator(user)
  remove_relationship(type: 'moderator_invite', name: user.name)
end

#unmoderated(**params) ⇒ Object

See Also:


115
116
117
# File 'lib/redd/models/subreddit.rb', line 115

%i(reports spam modqueue unmoderated edited).each do |type|
  define_method(type) { |**params| moderator_listing(type, **params) }
end

#unsubscribeObject

Remove the subreddit from the user's subscribed subreddits.


267
268
269
# File 'lib/redd/models/subreddit.rb', line 267

def unsubscribe
  subscribe(action: :unsub)
end

#update_stylesheet(text, reason: nil) ⇒ Object

Edit the subreddit's stylesheet.

Parameters:

  • text (String)

    the updated CSS

  • reason (String) (defaults to: nil)

    the reason for modifying the stylesheet


283
284
285
286
287
# File 'lib/redd/models/subreddit.rb', line 283

def update_stylesheet(text, reason: nil)
  params = { op: 'save', stylesheet_contents: text }
  params[:reason] = reason if reason
  @client.post("/r/#{get_attribute(:display_name)}/api/subreddit_stylesheet", params)
end

#upload_image(file:, image_type:, upload_type:, image_name: nil) ⇒ String

Upload a subreddit-specific image.

Parameters:

  • file (String, IO)

    the image file to upload

  • image_type ('jpg', 'png')

    the image type

  • upload_type ('img', 'header', 'icon', 'banner')

    where to upload the image

  • image_name (String) (defaults to: nil)

    the name of the image (if upload_type is 'img')

Returns:

  • (String)

    the url of the uploaded file


414
415
416
417
418
419
# File 'lib/redd/models/subreddit.rb', line 414

def upload_image(file:, image_type:, upload_type:, image_name: nil)
  file_data = HTTP::FormData::File.new(file)
  params = { img_type: image_type, upload_type: upload_type, file: file_data }
  params[:name] = image_name if upload_type.to_s == 'img'
  @client.post("/r/#{display_name}/api/upload_sr_img", params).body[:img_src]
end

#wiki_page(title) ⇒ WikiPage

Get a wiki page by its title.

Parameters:

  • title (String)

    the page's title

Returns:


45
46
47
# File 'lib/redd/models/subreddit.rb', line 45

def wiki_page(title)
  WikiPage.new(@client, title: title, subreddit: self)
end

#wiki_pagesArray<String>

Returns the subreddit's wiki pages.

Returns:

  • (Array<String>)

    the subreddit's wiki pages


38
39
40
# File 'lib/redd/models/subreddit.rb', line 38

def wiki_pages
  @client.get("/r/#{get_attribute(:display_name)}/wiki/pages").body[:data]
end

#wikibanned(**params) ⇒ Object


148
149
150
# File 'lib/redd/models/subreddit.rb', line 148

%i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
  define_method(type) { |**params| relationship_listing(type, **params) }
end

#wikicontributors(**params) ⇒ Object


148
149
150
# File 'lib/redd/models/subreddit.rb', line 148

%i(banned muted wikibanned contributors wikicontributors moderators).each do |type|
  define_method(type) { |**params| relationship_listing(type, **params) }
end