redd 0.7.8 → 0.7.9

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +34 -34
  3. data/.rspec +3 -3
  4. data/.rubocop.yml +5 -5
  5. data/.travis.yml +9 -9
  6. data/LICENSE.md +22 -22
  7. data/README.md +143 -143
  8. data/Rakefile +5 -5
  9. data/RedditKit.LICENSE.md +8 -8
  10. data/lib/redd.rb +50 -50
  11. data/lib/redd/access.rb +76 -76
  12. data/lib/redd/clients/base.rb +181 -181
  13. data/lib/redd/clients/base/account.rb +20 -20
  14. data/lib/redd/clients/base/identity.rb +22 -22
  15. data/lib/redd/clients/base/none.rb +27 -27
  16. data/lib/redd/clients/base/privatemessages.rb +33 -33
  17. data/lib/redd/clients/base/read.rb +113 -113
  18. data/lib/redd/clients/base/stream.rb +81 -81
  19. data/lib/redd/clients/base/submit.rb +19 -19
  20. data/lib/redd/clients/base/utilities.rb +104 -104
  21. data/lib/redd/clients/base/wikiread.rb +33 -33
  22. data/lib/redd/clients/installed.rb +56 -56
  23. data/lib/redd/clients/script.rb +41 -41
  24. data/lib/redd/clients/userless.rb +32 -32
  25. data/lib/redd/clients/web.rb +58 -58
  26. data/lib/redd/error.rb +151 -151
  27. data/lib/redd/objects/base.rb +39 -39
  28. data/lib/redd/objects/comment.rb +22 -22
  29. data/lib/redd/objects/labeled_multi.rb +13 -13
  30. data/lib/redd/objects/listing.rb +29 -29
  31. data/lib/redd/objects/more_comments.rb +11 -10
  32. data/lib/redd/objects/private_message.rb +28 -28
  33. data/lib/redd/objects/submission.rb +139 -139
  34. data/lib/redd/objects/subreddit.rb +330 -319
  35. data/lib/redd/objects/thing.rb +26 -26
  36. data/lib/redd/objects/thing/editable.rb +22 -22
  37. data/lib/redd/objects/thing/hideable.rb +18 -18
  38. data/lib/redd/objects/thing/inboxable.rb +25 -25
  39. data/lib/redd/objects/thing/messageable.rb +34 -34
  40. data/lib/redd/objects/thing/moderatable.rb +43 -43
  41. data/lib/redd/objects/thing/refreshable.rb +14 -14
  42. data/lib/redd/objects/thing/saveable.rb +21 -21
  43. data/lib/redd/objects/thing/votable.rb +33 -33
  44. data/lib/redd/objects/user.rb +52 -52
  45. data/lib/redd/objects/wiki_page.rb +15 -15
  46. data/lib/redd/rate_limit.rb +88 -88
  47. data/lib/redd/response/parse_json.rb +18 -18
  48. data/lib/redd/response/raise_error.rb +16 -16
  49. data/lib/redd/version.rb +4 -4
  50. data/redd.gemspec +31 -31
  51. data/spec/redd/objects/base_spec.rb +1 -1
  52. data/spec/redd/response/raise_error_spec.rb +11 -11
  53. data/spec/redd_spec.rb +5 -5
  54. data/spec/spec_helper.rb +71 -71
  55. metadata +21 -21
@@ -1,319 +1,330 @@
1
- require "fastimage"
2
- require_relative "thing"
3
-
4
- module Redd
5
- module Objects
6
- # A comment made on links.
7
- # @todo #subscribe! and #unsubscribe!
8
- class Subreddit < Thing
9
- include Thing::Messageable
10
- include Thing::Refreshable
11
-
12
- alias_property :header_image, :header_img
13
- alias_property :nsfw?, :over18
14
- alias_property :users_online, :accounts_active
15
- alias_property :type, :subreddit_type
16
- alias_property :times_gilded, :gilded
17
-
18
- # @!group Submissions
19
-
20
- # Submit a link or a text post to the subreddit.
21
- #
22
- # @param [String] title The title of the submission.
23
- # @param [String] captcha A possible captcha result to send if one
24
- # is required.
25
- # @param [String] identifier The identifier for the captcha if one
26
- # is required.
27
- # @param [String] text The text of the self-post.
28
- # @param [String] url The URL of the link.
29
- # @param [Boolean] resubmit Whether to post a link to the subreddit
30
- # despite it having been posted there before (you monster).
31
- # @param [Boolean] sendreplies Whether to send the replies to your
32
- # inbox.
33
- # @return [Objects::Thing] The returned result (url, id and name).
34
- def submit(
35
- title, captcha = nil, identifier = nil, text: nil, url: nil,
36
- resubmit: false, sendreplies: true
37
- )
38
-
39
- params = {
40
- extension: "json", title: title, sr: display_name,
41
- resubmit: resubmit, sendreplies: sendreplies
42
- }
43
-
44
- params.merge!(captcha: captcha, iden: identifier) if captcha
45
- params[:kind], params[:text] = :self, text if text
46
- params[:kind], params[:url] = :link, url if url
47
-
48
- response = post("/api/submit", params)
49
- Objects::Thing.new(self, response.body[:json][:data])
50
- end
51
-
52
- # Add a comment to the submission.
53
- # @param text [String] The text to comment.
54
- # @return [Objects::Comment] The reply.
55
- def add_comment(text)
56
- client.add_comment(self, text)
57
- end
58
-
59
- # @!endgroup
60
-
61
- # @!group Stylesheets
62
-
63
- # @return [String] The url for the subreddit's stylesheet.
64
- def stylesheet_url
65
- get("/r/#{display_name}/stylesheet").headers["location"]
66
- end
67
-
68
- # @return [String] The css for the subreddit.
69
- def stylesheet
70
- Faraday.get(stylesheet_url).body
71
- end
72
-
73
- # Edit the subreddit's stylesheet
74
- #
75
- # @param [String] contents The new CSS.
76
- # @param [String] reason Why you modified the stylesheet.
77
- # @author Takashi M (@beatak) and Avinash Dwarapu (@avidw)
78
- # @note https://www.reddit.com/r/naut/about/stylesheet/ is a good place
79
- # to test if you have an error.
80
- def edit_stylesheet(contents, reason = nil)
81
- params = {op: "save", stylesheet_contents: contents}
82
- params[:reason] = reason if reason
83
- post("/r/#{display_name}/api/subreddit_stylesheet", params)
84
- end
85
-
86
- # @!endgroup
87
-
88
- # @!group Invites
89
-
90
- # Accept a moderator invite from a subreddit.
91
- def accept_moderator_invite!
92
- post("/r/#{display_name}/api/accept_moderator_invite")
93
- end
94
-
95
- # Stop being a contributor of the subreddit.
96
- def leave_contributor_status!
97
- post("/api/leavecontributor", id: fullname)
98
- end
99
-
100
- # Stop being a moderator of the subreddit.
101
- def leave_moderator_status!
102
- post("/api/leavemoderator", id: fullname)
103
- end
104
-
105
- # @!endgroup
106
-
107
- # @!group Flairs
108
-
109
- # Get a list of everbody on the subreddit with a user flair.
110
- #
111
- # @param [Hash] params A list of params to send with the request.
112
- # @option params [String] :after Return results after the given
113
- # fullname.
114
- # @option params [String] :before Return results before the given
115
- # fullname.
116
- # @option params [Integer] :count The number of items already seen in the
117
- # listing.
118
- # @option params [1..1000] :limit The maximum number of things to
119
- # return.
120
- # @option params [String] :name The username when getting the flair of
121
- # just one user.
122
- # @return [Objects::Listing<Hash>] A listing of flair hashes.
123
- def get_flairlist(**params)
124
- body = get("/r/#{display_name}/api/flairlist.json", params).body
125
- client.object_from_body(
126
- kind: "Listing",
127
- data: {
128
- children: body[:users],
129
- before: body[:prev],
130
- after: body[:next]
131
- }
132
- )
133
- end
134
-
135
- # Get the flair of a user.
136
- #
137
- # @param [Objects::User, String] user The user to find.
138
- # @return [Hash, nil] Flair info about the user or nil if nobody was
139
- # found.
140
- def get_flair(user)
141
- username = client.property(user, :name)
142
- flair = get_flairlist(user: username).first
143
- flair if flair[:user].casecmp(username) == 0
144
- end
145
-
146
- # Set the flair of a user or link.
147
- # @param [Objects::Subreddit, Objects::User] thing The user or link to
148
- # set the flair to.
149
- # @param [:user, :link] type The type of thing.
150
- # @param [String] text The text to set the flair to.
151
- # @param [String] css_class The css_class of the flair.
152
- def set_flair(thing, type = nil, text = nil, css_class = nil)
153
- params = {text: text, css_class: css_class}
154
- if thing.is_a?(Objects::User) || type == :user
155
- params[:name] = client.property(thing, :name)
156
- elsif thing.is_a?(Objects::Submission) || type == :link
157
- params[:link] = client.property(thing, :fullname)
158
- else
159
- fail "You should provide a proper type."
160
- end
161
-
162
- post("/r/#{display_name}/api/flair", params)
163
- end
164
-
165
- # @!endgroup
166
-
167
- # @!group Listings
168
-
169
- # @!method get_hot(**params)
170
- # @!method get_new(**params)
171
- # @!method get_top(**params)
172
- # @!method get_controversial(**params)
173
- # @!method get_comments(**params)
174
- #
175
- # Get the appropriate listing.
176
- # @param params [Hash] A list of params to send with the request.
177
- # @option params [String] :after Return results after the given
178
- # fullname.
179
- # @option params [String :before Return results before the given
180
- # fullname.
181
- # @option params [Integer] :count (0) The number of items already seen
182
- # in the listing.
183
- # @option params [1..100] :limit (25) The maximum number of things to
184
- # return.
185
- # @option params [:hour, :day, :week, :month, :year, :all] :t The
186
- # time period to consider when sorting.
187
- #
188
- # @note The option :t only applies to the top and controversial sorts.
189
- # @return [Objects::Listing<Objects::Thing>]
190
- %w(hot new top controversial comments).each do |sort|
191
- define_method :"get_#{sort}" do |**params|
192
- client.send(:"get_#{sort}", self, **params)
193
- end
194
- end
195
-
196
- # Search.
197
- # @param query [String] The query string.
198
- # @param params [Hash] A list of params to send with the request.
199
- # @option params [String] :after Return results after the given
200
- # fullname.
201
- # @option params [String :before Return results before the given
202
- # fullname.
203
- # @option params [Integer] :count The number of items already seen in
204
- # the listing.
205
- # @option params [1..100] :limit The maximum number of things to
206
- # return.
207
- # @option params [:cloudsearch, :lucene, :plain] :syntax The type of
208
- # syntax to use.
209
- # @option params [:relevance, :new, :hot, :top, :comments] :sort The
210
- # way to sort the results.
211
- # @option params [:hour, :day, :week, :month, :year, :all] :t The
212
- # time period to consider when sorting.
213
- #
214
- # @note The option :t only applies to the top and controversial sorts.
215
- # @return [Objects::Listing<Objects::Thing>]
216
- def search(query, **params)
217
- client.search(query, self, **params)
218
- end
219
-
220
- # @!endgroup
221
-
222
- # @!group Moderation
223
-
224
- # @!method get_reports(**params)
225
- # @!method get_spam(**params)
226
- # @!method get_modqueue(**params)
227
- # @!method get_unmoderated(**params)
228
- # @!method get_edited(**params)
229
- #
230
- # Get the appropriate moderator listing.
231
- # @param [Hash] params A list of params to send with the request.
232
- # @option params [String] :after Return results after the given
233
- # fullname.
234
- # @option params [String] :before Return results before the given
235
- # fullname.
236
- # @option params [Integer] :count The number of items already seen
237
- # in the listing.
238
- # @option params [1..100] :limit The maximum number of things to
239
- # return.
240
- # @option params :location No idea what this does.
241
- # @option params [:links, :comments] :only The type of things to show.
242
- #
243
- # @return [Objects::Listing<Objects::Thing>]
244
- # @see https://www.reddit.com/dev/api#GET_about_{location}
245
- %w(reports spam modqueue unmoderated edited).each do |sort|
246
- define_method :"get_#{sort}" do |**params|
247
- client.request_object(
248
- :get, "/r/#{display_name}/about/#{sort}", params
249
- )
250
- end
251
- end
252
-
253
- # @return [Objects::Base] The current settings of a subreddit.
254
- def admin_about
255
- client.request_object(:get, "/r/#{display_name}/about/edit.json")
256
- end
257
-
258
- # Edit the subreddit's settings
259
- # @param [Hash] attributes The subreddit's new settings.
260
- # @note This method may make additional requests if not all of the
261
- # required attributes are provided. Take a look at the source for the
262
- # required attributes required to avoid making the additional request.
263
- # @see https://github.com/alaycock/MeetCal-bot/blob/master/serverInfo.conf
264
- def admin_edit(attributes)
265
- params = {
266
- # Subreddit name
267
- sr: fullname,
268
- # Apparently useless options
269
- show_cname_sidebar: true,
270
- :"header-title" => title
271
- }
272
-
273
- required = %i(
274
- allow_top collapse_deleted_comments comment_score_hide_mins
275
- css_on_cname description exclude_banned_modqueue lang link_type name
276
- over_18 public_description public_traffic show_media spam_comments
277
- spam_links spam_selfposts submit_link_label submit_text
278
- submit_text_label title type wiki_edit_age wiki_edit_karma wikimode
279
- )
280
-
281
- if required.all? { |key| attributes.key?(key) }
282
- params.merge!(attributes)
283
- else
284
- about = admin_about
285
- final = about
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)
296
- params.merge!(final)
297
- end
298
-
299
- post("/api/site_admin", params)
300
- end
301
-
302
- # Add or replace the subreddit image or header logo.
303
- # @param [String, IO] file The path/url to the file or the file itself.
304
- # @param [String] name The name of the uploaded file.
305
- # @return [String] The url of the image on reddit's CDN.
306
- def upload_image(file, name = nil)
307
- io = (file.is_a?(IO) ? file : File.open(file, "r"))
308
- type = FastImage.type(io)
309
- payload = Faraday::UploadIO.new(io, "image/#{type}")
310
-
311
- params = {file: payload, header: (name ? 0 : 1), img_type: type}
312
- params[:name] = name if name
313
- post("/r/#{display_name}/api/upload_sr_img", params).body[:img_src]
314
- end
315
-
316
- # @!endgroup
317
- end
318
- end
319
- end
1
+ require "fastimage"
2
+ require_relative "thing"
3
+
4
+ module Redd
5
+ module Objects
6
+ # A comment made on links.
7
+ # @todo #subscribe! and #unsubscribe!
8
+ class Subreddit < Thing
9
+ include Thing::Messageable
10
+ include Thing::Refreshable
11
+
12
+ alias_property :header_image, :header_img
13
+ alias_property :nsfw?, :over18
14
+ alias_property :users_online, :accounts_active
15
+ alias_property :type, :subreddit_type
16
+ alias_property :times_gilded, :gilded
17
+
18
+ # @!group Submissions
19
+
20
+ # Submit a link or a text post to the subreddit.
21
+ #
22
+ # @param [String] title The title of the submission.
23
+ # @param [String] captcha A possible captcha result to send if one
24
+ # is required.
25
+ # @param [String] identifier The identifier for the captcha if one
26
+ # is required.
27
+ # @param [String] text The text of the self-post.
28
+ # @param [String] url The URL of the link.
29
+ # @param [Boolean] resubmit Whether to post a link to the subreddit
30
+ # despite it having been posted there before (you monster).
31
+ # @param [Boolean] sendreplies Whether to send the replies to your
32
+ # inbox.
33
+ # @return [Objects::Thing] The returned result (url, id and name).
34
+ def submit(
35
+ title, captcha = nil, identifier = nil, text: nil, url: nil,
36
+ resubmit: false, sendreplies: true
37
+ )
38
+
39
+ params = {
40
+ extension: "json", title: title, sr: display_name,
41
+ resubmit: resubmit, sendreplies: sendreplies
42
+ }
43
+
44
+ params.merge!(captcha: captcha, iden: identifier) if captcha
45
+ params[:kind], params[:text] = :self, text if text
46
+ params[:kind], params[:url] = :link, url if url
47
+
48
+ response = post("/api/submit", params)
49
+ Objects::Thing.new(self, response.body[:json][:data])
50
+ end
51
+
52
+ # Add a comment to the submission.
53
+ # @param text [String] The text to comment.
54
+ # @return [Objects::Comment] The reply.
55
+ def add_comment(text)
56
+ client.add_comment(self, text)
57
+ end
58
+
59
+ # @!endgroup
60
+
61
+ # @!group Stylesheets
62
+
63
+ # @return [String] The url for the subreddit's stylesheet.
64
+ def stylesheet_url
65
+ get("/r/#{display_name}/stylesheet").headers["location"]
66
+ end
67
+
68
+ # @return [String] The css for the subreddit.
69
+ def stylesheet
70
+ Faraday.get(stylesheet_url).body
71
+ end
72
+
73
+ # Edit the subreddit's stylesheet
74
+ #
75
+ # @param [String] contents The new CSS.
76
+ # @param [String] reason Why you modified the stylesheet.
77
+ # @author Takashi M (@beatak) and Avinash Dwarapu (@avidw)
78
+ # @note https://www.reddit.com/r/naut/about/stylesheet/ is a good place
79
+ # to test if you have an error.
80
+ def edit_stylesheet(contents, reason = nil)
81
+ params = {op: "save", stylesheet_contents: contents}
82
+ params[:reason] = reason if reason
83
+ post("/r/#{display_name}/api/subreddit_stylesheet", params)
84
+ end
85
+
86
+ # @!endgroup
87
+
88
+ # @!group Invites
89
+
90
+ # Accept a moderator invite from a subreddit.
91
+ def accept_moderator_invite!
92
+ post("/r/#{display_name}/api/accept_moderator_invite")
93
+ end
94
+
95
+ # Stop being a contributor of the subreddit.
96
+ def leave_contributor_status!
97
+ post("/api/leavecontributor", id: fullname)
98
+ end
99
+
100
+ # Stop being a moderator of the subreddit.
101
+ def leave_moderator_status!
102
+ post("/api/leavemoderator", id: fullname)
103
+ end
104
+
105
+ # @!endgroup
106
+
107
+ # @!group Flairs
108
+
109
+ # Get a list of everbody on the subreddit with a user flair.
110
+ #
111
+ # @param [Hash] params A list of params to send with the request.
112
+ # @option params [String] :after Return results after the given
113
+ # fullname.
114
+ # @option params [String] :before Return results before the given
115
+ # fullname.
116
+ # @option params [Integer] :count The number of items already seen in the
117
+ # listing.
118
+ # @option params [1..1000] :limit The maximum number of things to
119
+ # return.
120
+ # @option params [String] :name The username when getting the flair of
121
+ # just one user.
122
+ # @return [Objects::Listing<Hash>] A listing of flair hashes.
123
+ def get_flairlist(**params)
124
+ body = get("/r/#{display_name}/api/flairlist.json", params).body
125
+ client.object_from_body(
126
+ kind: "Listing",
127
+ data: {
128
+ children: body[:users],
129
+ before: body[:prev],
130
+ after: body[:next]
131
+ }
132
+ )
133
+ end
134
+
135
+ # Get the flair of a user.
136
+ #
137
+ # @param [Objects::User, String] user The user to find.
138
+ # @return [Hash, nil] Flair info about the user or nil if nobody was
139
+ # found.
140
+ def get_flair(user)
141
+ username = client.property(user, :name)
142
+ flair = get_flairlist(user: username).first
143
+ flair if flair[:user].casecmp(username) == 0
144
+ end
145
+
146
+ # Set the flair of a user or link.
147
+ # @param [Objects::Subreddit, Objects::User] thing The user or link to
148
+ # set the flair to.
149
+ # @param [:user, :link] type The type of thing.
150
+ # @param [String] text The text to set the flair to.
151
+ # @param [String] css_class The css_class of the flair.
152
+ def set_flair(thing, type = nil, text = nil, css_class = nil)
153
+ params = {text: text, css_class: css_class}
154
+ if thing.is_a?(Objects::User) || type == :user
155
+ params[:name] = client.property(thing, :name)
156
+ elsif thing.is_a?(Objects::Submission) || type == :link
157
+ params[:link] = client.property(thing, :fullname)
158
+ else
159
+ fail "You should provide a proper type."
160
+ end
161
+
162
+ post("/r/#{display_name}/api/flair", params)
163
+ end
164
+
165
+ # @!endgroup
166
+
167
+ # @!group Listings
168
+
169
+ # @!method get_hot(**params)
170
+ # @!method get_new(**params)
171
+ # @!method get_top(**params)
172
+ # @!method get_controversial(**params)
173
+ # @!method get_comments(**params)
174
+ #
175
+ # Get the appropriate listing.
176
+ # @param params [Hash] A list of params to send with the request.
177
+ # @option params [String] :after Return results after the given
178
+ # fullname.
179
+ # @option params [String :before Return results before the given
180
+ # fullname.
181
+ # @option params [Integer] :count (0) The number of items already seen
182
+ # in the listing.
183
+ # @option params [1..100] :limit (25) The maximum number of things to
184
+ # return.
185
+ # @option params [:hour, :day, :week, :month, :year, :all] :t The
186
+ # time period to consider when sorting.
187
+ #
188
+ # @note The option :t only applies to the top and controversial sorts.
189
+ # @return [Objects::Listing<Objects::Thing>]
190
+ %w(hot new top controversial comments).each do |sort|
191
+ define_method :"get_#{sort}" do |**params|
192
+ client.send(:"get_#{sort}", self, **params)
193
+ end
194
+ end
195
+
196
+ # Search.
197
+ # @param query [String] The query string.
198
+ # @param params [Hash] A list of params to send with the request.
199
+ # @option params [String] :after Return results after the given
200
+ # fullname.
201
+ # @option params [String :before Return results before the given
202
+ # fullname.
203
+ # @option params [Integer] :count The number of items already seen in
204
+ # the listing.
205
+ # @option params [1..100] :limit The maximum number of things to
206
+ # return.
207
+ # @option params [:cloudsearch, :lucene, :plain] :syntax The type of
208
+ # syntax to use.
209
+ # @option params [:relevance, :new, :hot, :top, :comments] :sort The
210
+ # way to sort the results.
211
+ # @option params [:hour, :day, :week, :month, :year, :all] :t The
212
+ # time period to consider when sorting.
213
+ #
214
+ # @note The option :t only applies to the top and controversial sorts.
215
+ # @return [Objects::Listing<Objects::Thing>]
216
+ def search(query, **params)
217
+ client.search(query, self, **params)
218
+ end
219
+
220
+ # @!endgroup
221
+
222
+ # @!group Moderation
223
+
224
+ # @!method get_reports(**params)
225
+ # @!method get_spam(**params)
226
+ # @!method get_modqueue(**params)
227
+ # @!method get_unmoderated(**params)
228
+ # @!method get_edited(**params)
229
+ #
230
+ # Get the appropriate moderator listing.
231
+ # @param [Hash] params A list of params to send with the request.
232
+ # @option params [String] :after Return results after the given
233
+ # fullname.
234
+ # @option params [String] :before Return results before the given
235
+ # fullname.
236
+ # @option params [Integer] :count The number of items already seen
237
+ # in the listing.
238
+ # @option params [1..100] :limit The maximum number of things to
239
+ # return.
240
+ # @option params :location No idea what this does.
241
+ # @option params [:links, :comments] :only The type of things to show.
242
+ #
243
+ # @return [Objects::Listing<Objects::Thing>]
244
+ # @see https://www.reddit.com/dev/api#GET_about_{location}
245
+ %w(reports spam modqueue unmoderated edited).each do |sort|
246
+ define_method :"get_#{sort}" do |**params|
247
+ client.request_object(
248
+ :get, "/r/#{display_name}/about/#{sort}", params
249
+ )
250
+ end
251
+ end
252
+
253
+ # @return [Objects::Base] The current settings of a subreddit.
254
+ def admin_about
255
+ client.request_object(:get, "/r/#{display_name}/about/edit.json")
256
+ end
257
+
258
+ # @return [Objects::Base] The current moderators of a subreddit.
259
+ def moderator_about
260
+ body = get("/r/#{display_name}/about/moderators.json").body
261
+ client.object_from_body(
262
+ kind: "Listing",
263
+ data: {
264
+ children: body[:data][:children]
265
+ }
266
+ )
267
+ end
268
+
269
+ # Edit the subreddit's settings
270
+ # @param [Hash] attributes The subreddit's new settings.
271
+ # @note This method may make additional requests if not all of the
272
+ # required attributes are provided. Take a look at the source for the
273
+ # required attributes required to avoid making the additional request.
274
+ # @see https://github.com/alaycock/MeetCal-bot/blob/master/serverInfo.conf
275
+ def admin_edit(attributes)
276
+ params = {
277
+ # Subreddit name
278
+ sr: fullname,
279
+ # Apparently useless options
280
+ show_cname_sidebar: true,
281
+ :"header-title" => title
282
+ }
283
+
284
+ required = %i(
285
+ allow_top collapse_deleted_comments comment_score_hide_mins
286
+ css_on_cname description exclude_banned_modqueue lang link_type name
287
+ over_18 public_description public_traffic show_media spam_comments
288
+ spam_links spam_selfposts submit_link_label submit_text
289
+ submit_text_label title type wiki_edit_age wiki_edit_karma wikimode
290
+ )
291
+
292
+ if required.all? { |key| attributes.key?(key) }
293
+ params.merge!(attributes)
294
+ else
295
+ about = admin_about
296
+ final = about
297
+ .select { |k, _| required.include?(k) }
298
+ .merge(
299
+ name: display_name,
300
+ type: about[:subreddit_type],
301
+ lang: about[:language],
302
+ link_type: about[:content_options],
303
+ allow_top: true,
304
+ css_on_cname: true
305
+ )
306
+ .merge(attributes)
307
+ params.merge!(final)
308
+ end
309
+
310
+ post("/api/site_admin", params)
311
+ end
312
+
313
+ # Add or replace the subreddit image or header logo.
314
+ # @param [String, IO] file The path/url to the file or the file itself.
315
+ # @param [String] name The name of the uploaded file.
316
+ # @return [String] The url of the image on reddit's CDN.
317
+ def upload_image(file, name = nil)
318
+ io = (file.is_a?(IO) ? file : File.open(file, "r"))
319
+ type = FastImage.type(io)
320
+ payload = Faraday::UploadIO.new(io, "image/#{type}")
321
+
322
+ params = {file: payload, header: (name ? 0 : 1), img_type: type}
323
+ params[:name] = name if name
324
+ post("/r/#{display_name}/api/upload_sr_img", params).body[:img_src]
325
+ end
326
+
327
+ # @!endgroup
328
+ end
329
+ end
330
+ end