redd 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -8
- data/bin/console +42 -16
- data/lib/redd.rb +50 -19
- data/lib/redd/api_client.rb +18 -27
- data/lib/redd/auth_strategies/auth_strategy.rb +4 -3
- data/lib/redd/auth_strategies/script.rb +6 -1
- data/lib/redd/auth_strategies/userless.rb +6 -1
- data/lib/redd/auth_strategies/web.rb +4 -4
- data/lib/redd/models/access.rb +6 -1
- data/lib/redd/models/basic_model.rb +12 -55
- data/lib/redd/models/comment.rb +24 -28
- data/lib/redd/models/front_page.rb +1 -1
- data/lib/redd/models/gildable.rb +13 -0
- data/lib/redd/models/inboxable.rb +3 -3
- data/lib/redd/models/lazy_model.rb +7 -8
- data/lib/redd/models/listing.rb +6 -7
- data/lib/redd/models/live_thread.rb +9 -11
- data/lib/redd/models/mod_mail.rb +19 -24
- data/lib/redd/models/more_comments.rb +1 -1
- data/lib/redd/models/multireddit.rb +9 -13
- data/lib/redd/models/postable.rb +3 -3
- data/lib/redd/models/private_message.rb +18 -9
- data/lib/redd/models/searchable.rb +1 -1
- data/lib/redd/models/session.rb +31 -2
- data/lib/redd/models/submission.rb +26 -14
- data/lib/redd/models/subreddit.rb +115 -19
- data/lib/redd/models/user.rb +21 -9
- data/lib/redd/models/wiki_page.rb +8 -11
- data/lib/redd/utilities/unmarshaller.rb +3 -2
- data/lib/redd/version.rb +1 -1
- data/redd.gemspec +1 -1
- metadata +4 -5
- data/TODO.md +0 -8
- data/lib/redd/auth_strategies/installed.rb +0 -22
data/lib/redd/models/postable.rb
CHANGED
@@ -21,7 +21,7 @@ module Redd
|
|
21
21
|
# Save a link or comment to the user's account.
|
22
22
|
# @param category [String] a category to save to
|
23
23
|
def save(category = nil)
|
24
|
-
params = { id:
|
24
|
+
params = { id: get_attribute(:name) }
|
25
25
|
params[:category] = category if category
|
26
26
|
@client.post('/api/save', params)
|
27
27
|
end
|
@@ -33,12 +33,12 @@ module Redd
|
|
33
33
|
|
34
34
|
# Hide a link from the user.
|
35
35
|
def hide
|
36
|
-
@client.post('/api/hide', id: get_attribute(:
|
36
|
+
@client.post('/api/hide', id: get_attribute(:name))
|
37
37
|
end
|
38
38
|
|
39
39
|
# Unhide a previously hidden link.
|
40
40
|
def unhide
|
41
|
-
@client.post('/api/unhide', id: get_attribute(:
|
41
|
+
@client.post('/api/unhide', id: get_attribute(:name))
|
42
42
|
end
|
43
43
|
|
44
44
|
# Upvote the model.
|
@@ -11,19 +11,28 @@ module Redd
|
|
11
11
|
include Inboxable
|
12
12
|
include Replyable
|
13
13
|
|
14
|
-
# Make a Message from its id.
|
15
|
-
# @option hash [String] :id the post's id (e.g. abc123)
|
16
|
-
# @return [Submission]
|
17
|
-
def self.from_response(client, hash)
|
18
|
-
# FIXME: This returns the entire conversation, not the specific message. Possible to search,
|
19
|
-
# because depth of replies is just one.
|
20
|
-
super
|
21
|
-
end
|
22
|
-
|
23
14
|
# Delete the message from the user's inbox.
|
24
15
|
def delete
|
25
16
|
@client.post('/api/del_msg', id: get_attribute(:name))
|
26
17
|
end
|
18
|
+
|
19
|
+
# Mute the author of the message.
|
20
|
+
def mute_author
|
21
|
+
@client.post('/api/mute_message_author', id: get_attribute(:name))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Unmute the author of the message.
|
25
|
+
def unmute_author
|
26
|
+
@client.post('/api/unmute_message_author', id: get_attribute(:name))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def default_loader
|
32
|
+
# FIXME: This returns the entire conversation, not the specific message. Possible to search,
|
33
|
+
# because depth of replies is just one.
|
34
|
+
{}
|
35
|
+
end
|
27
36
|
end
|
28
37
|
end
|
29
38
|
end
|
@@ -20,7 +20,7 @@ module Redd
|
|
20
20
|
# @option params [String] :restrict_to restrict by subreddit (prefer {Subreddit#search})
|
21
21
|
# @return [Listing<Comment, Submission>] the search results
|
22
22
|
def search(query, **params)
|
23
|
-
params[:q] = query
|
23
|
+
params[:q] = query
|
24
24
|
params[:t] = params.delete(:time) if params.key?(:time)
|
25
25
|
if params[:restrict_to]
|
26
26
|
subreddit = params.delete(:restrict_to)
|
data/lib/redd/models/session.rb
CHANGED
@@ -94,20 +94,49 @@ module Redd
|
|
94
94
|
@client.post('/api/read_all_messages')
|
95
95
|
end
|
96
96
|
|
97
|
+
# @return [Hash] the user's preferences
|
98
|
+
def my_preferences
|
99
|
+
@client.get('/api/v1/me/prefs').body
|
100
|
+
end
|
101
|
+
|
102
|
+
# Edit the user's preferences.
|
103
|
+
# @param new_prefs [Hash] the changed preferences
|
104
|
+
# @return [Hash] the new preferences
|
105
|
+
# @see #my_preferences
|
106
|
+
def edit_preferences(new_prefs = {})
|
107
|
+
@client.request(
|
108
|
+
:patch, '/api/v1/me/prefs',
|
109
|
+
headers: { 'Content-Type' => 'application/json' },
|
110
|
+
body: JSON.generate(new_prefs)
|
111
|
+
).body
|
112
|
+
end
|
113
|
+
|
97
114
|
# @return [Array<User>] the logged-in user's friends
|
98
115
|
def friends
|
99
116
|
@client.get('/api/v1/me/friends').body[:data][:children].map do |h|
|
100
|
-
User.
|
117
|
+
User.new(@client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date])
|
101
118
|
end
|
102
119
|
end
|
103
120
|
|
104
121
|
# @return [Array<User>] users blocked by the logged-in user
|
105
122
|
def blocked
|
106
123
|
@client.get('/prefs/blocked').body[:data][:children].map do |h|
|
107
|
-
User.
|
124
|
+
User.new(@client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [Array<User>] users blocked by the logged-in user
|
129
|
+
def trusted
|
130
|
+
@client.get('/prefs/trusted').body[:data][:children].map do |h|
|
131
|
+
User.new(@client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date])
|
108
132
|
end
|
109
133
|
end
|
110
134
|
|
135
|
+
# @return [Array<String>] a list of categories the user's items are saved in
|
136
|
+
def saved_categories
|
137
|
+
@client.get('/api/saved_categories').body
|
138
|
+
end
|
139
|
+
|
111
140
|
# Return a listing of the user's subreddits.
|
112
141
|
#
|
113
142
|
# @param type ['subscriber', 'contributor', 'moderator'] the type of subreddits
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'lazy_model'
|
4
|
+
require_relative 'gildable'
|
4
5
|
require_relative 'moderatable'
|
5
6
|
require_relative 'postable'
|
6
7
|
require_relative 'replyable'
|
@@ -12,25 +13,17 @@ module Redd
|
|
12
13
|
module Models
|
13
14
|
# A text or link post.
|
14
15
|
class Submission < LazyModel
|
16
|
+
include Gildable
|
15
17
|
include Moderatable
|
16
18
|
include Postable
|
17
19
|
include Replyable
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
# Make a Submission from its id.
|
23
|
-
# @option hash [String] :id the post's id (e.g. abc123)
|
21
|
+
# Create a Subreddit from its fullname.
|
22
|
+
# @param client [APIClient] the api client to initialize the object with
|
23
|
+
# @param id [String] the fullname
|
24
24
|
# @return [Submission]
|
25
|
-
def self.
|
26
|
-
|
27
|
-
new(client, hash) do |c|
|
28
|
-
# `data` is a pair (2-element array):
|
29
|
-
# - data[0] is a one-item listing containing the submission
|
30
|
-
# - data[1] is listing of comments
|
31
|
-
data = c.get("/comments/#{link_id}").body
|
32
|
-
data[0][:data][:children][0][:data].merge(comments: c.unmarshal(data[1]))
|
33
|
-
end
|
25
|
+
def self.from_id(client, id)
|
26
|
+
new(client, name: id)
|
34
27
|
end
|
35
28
|
|
36
29
|
# Get all submissions for the same url.
|
@@ -98,6 +91,25 @@ module Redd
|
|
98
91
|
def unlock
|
99
92
|
@client.post('/api/unlock', id: get_attribute(:name))
|
100
93
|
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def default_loader
|
98
|
+
# Ensure we have the link's id.
|
99
|
+
id = @attributes[:id] ? @attributes[:id] : @attributes.fetch(:name).sub('t3_', '')
|
100
|
+
response = @client.get("/comments/#{id}").body
|
101
|
+
# `response` is a pair (2-element array):
|
102
|
+
# - response[0] is a one-item listing containing the submission
|
103
|
+
# - response[1] is listing of comments
|
104
|
+
response[0][:data][:children][0][:data].merge(comments: @client.unmarshal(response[1]))
|
105
|
+
end
|
106
|
+
|
107
|
+
def after_initialize
|
108
|
+
if @attributes[:subreddit]
|
109
|
+
@attributes[:subreddit] = Subreddit.from_id(@client, @attributes[:subreddit])
|
110
|
+
end
|
111
|
+
@attributes[:author] = User.from_id(@client, @attributes[:author]) if @attributes[:author]
|
112
|
+
end
|
101
113
|
end
|
102
114
|
end
|
103
115
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'basic_model'
|
3
4
|
require_relative 'lazy_model'
|
4
5
|
require_relative 'messageable'
|
5
6
|
require_relative 'searchable'
|
@@ -12,14 +13,6 @@ module Redd
|
|
12
13
|
include Messageable
|
13
14
|
include Searchable
|
14
15
|
|
15
|
-
# A list of keys that are required by #modify_settings.
|
16
|
-
SETTINGS_KEYS = %i(allow_images allow_top collapse_deleted_comments comment_score_hide_mins
|
17
|
-
description exclude_banned_modqueue header-title hide_ads lang link_type
|
18
|
-
over_18 public_description public_traffic show_media show_media_preview
|
19
|
-
spam_comments spam_links spam_selfposts spoilers_enabled submit_link_label
|
20
|
-
submit_text submit_text_label suggested_comment_sort theme_sr
|
21
|
-
theme_sr_update title type wiki_edit_age wiki_edit_karma wikimode).freeze
|
22
|
-
|
23
16
|
# A mapping from keys returned by #settings to keys required by #modify_settings
|
24
17
|
SETTINGS_MAP = {
|
25
18
|
subreddit_type: :type,
|
@@ -29,20 +22,16 @@ module Redd
|
|
29
22
|
header_hover_text: :'header-title'
|
30
23
|
}.freeze
|
31
24
|
|
32
|
-
#
|
33
|
-
# @
|
34
|
-
|
35
|
-
def self.from_response(client, hash)
|
36
|
-
name = hash.fetch(:display_name)
|
37
|
-
new(client, hash) { |c| c.get("/r/#{name}/about").body[:data] }
|
38
|
-
end
|
25
|
+
# Represents a moderator action, part of a moderation log.
|
26
|
+
# @see Subreddit#log
|
27
|
+
class ModAction < BasicModel; end
|
39
28
|
|
40
29
|
# Create a Subreddit from its name.
|
41
30
|
# @param client [APIClient] the api client to initialize the object with
|
42
31
|
# @param id [String] the subreddit name
|
43
32
|
# @return [Subreddit]
|
44
33
|
def self.from_id(client, id)
|
45
|
-
|
34
|
+
new(client, display_name: id)
|
46
35
|
end
|
47
36
|
|
48
37
|
# @return [Array<String>] the subreddit's wiki pages
|
@@ -54,7 +43,7 @@ module Redd
|
|
54
43
|
# @param title [String] the page's title
|
55
44
|
# @return [WikiPage]
|
56
45
|
def wiki_page(title)
|
57
|
-
WikiPage.
|
46
|
+
WikiPage.new(@client, title: title, subreddit: self)
|
58
47
|
end
|
59
48
|
|
60
49
|
# Search a subreddit.
|
@@ -198,7 +187,7 @@ module Redd
|
|
198
187
|
params[:kind] = url ? 'link' : 'self'
|
199
188
|
params[:url] = url if url
|
200
189
|
params[:text] = text if text
|
201
|
-
Submission.
|
190
|
+
Submission.new(@client, @client.post('/api/submit', params).body[:json][:data])
|
202
191
|
end
|
203
192
|
|
204
193
|
# Compose a message to the moderators of a subreddit.
|
@@ -293,10 +282,117 @@ module Redd
|
|
293
282
|
@client.post('/api/site_admin', full_params)
|
294
283
|
end
|
295
284
|
|
285
|
+
# Get the moderation log.
|
286
|
+
# @param params [Hash] a list of params to send with the request
|
287
|
+
# @option params [String] :after return results after the given fullname
|
288
|
+
# @option params [String] :before return results before the given fullname
|
289
|
+
# @option params [Integer] :count the number of items already seen in the listing
|
290
|
+
# @option params [1..100] :limit the maximum number of things to return
|
291
|
+
# @option params [String] :type filter events to a specific type
|
292
|
+
#
|
293
|
+
# @return [Listing<ModAction>]
|
294
|
+
def mod_log(**params)
|
295
|
+
@client.model(:get, "/r/#{get_attribute(:display_name)}/about/log", params)
|
296
|
+
end
|
297
|
+
|
298
|
+
# Invite a user to moderate this subreddit.
|
299
|
+
# @param user [User] the user to invite
|
300
|
+
# @param permissions [String] the permission string to invite the user with
|
301
|
+
def invite_moderator(user, permissions: '+all')
|
302
|
+
add_relationship(type: 'moderator_invite', name: user.name, permissions: permissions)
|
303
|
+
end
|
304
|
+
|
305
|
+
# Take back a moderator request.
|
306
|
+
# @param user [User] the requested user
|
307
|
+
def uninvite_moderator(user)
|
308
|
+
remove_relationship(type: 'moderator_invite', name: user.name)
|
309
|
+
end
|
310
|
+
|
311
|
+
# Accept an invite to become a moderator of this subreddit.
|
312
|
+
def accept_moderator_invite
|
313
|
+
@client.post("/r/#{get_attribute(:display_name)}/api/accept_moderator_invite")
|
314
|
+
end
|
315
|
+
|
316
|
+
# Dethrone a moderator.
|
317
|
+
# @param user [User] the user to remove
|
318
|
+
def remove_moderator(user)
|
319
|
+
remove_relationship(type: 'moderator', name: user.name)
|
320
|
+
end
|
321
|
+
|
322
|
+
# Leave from being a moderator on a subreddit.
|
323
|
+
def leave_moderator
|
324
|
+
@client.post('/api/leavemoderator', id: get_attribute(:name))
|
325
|
+
end
|
326
|
+
|
327
|
+
# Add a contributor to the subreddit.
|
328
|
+
# @param user [User] the user to add
|
329
|
+
def add_contributor(user)
|
330
|
+
add_relationship(type: 'contributor', name: user.name)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Remove a contributor from the subreddit.
|
334
|
+
# @param user [User] the user to remove
|
335
|
+
def remove_contributor(user)
|
336
|
+
remove_relationship(type: 'contributor', name: user.name)
|
337
|
+
end
|
338
|
+
|
339
|
+
# Leave from being a contributor on a subreddit.
|
340
|
+
def leave_contributor
|
341
|
+
@client.post('/api/leavecontributor', id: get_attribute(:name))
|
342
|
+
end
|
343
|
+
|
344
|
+
# Ban a user from a subreddit.
|
345
|
+
# @param user [User] the user to ban
|
346
|
+
# @param params [Hash] additional options to supply with the request
|
347
|
+
# @option params [String] :ban_reason the reason for the ban
|
348
|
+
# @option params [String] :ban_message a message sent to the banned user
|
349
|
+
# @option params [String] :note a note that only moderators can see
|
350
|
+
# @option params [Integer] :duration the number of days to ban the user (if temporary)
|
351
|
+
def ban(user, **params)
|
352
|
+
add_relationship(type: 'banned', name: user.name, **params)
|
353
|
+
end
|
354
|
+
|
355
|
+
# Remove a ban on a user.
|
356
|
+
# @param user [User] the user to unban
|
357
|
+
def unban(user)
|
358
|
+
remove_relationship(type: 'banned', name: user.name)
|
359
|
+
end
|
360
|
+
|
361
|
+
# Allow a user to contribute to the wiki.
|
362
|
+
# @param user [User] the user to add
|
363
|
+
def add_wiki_contributor(user)
|
364
|
+
add_relationship(type: 'wikicontributor', name: user.name)
|
365
|
+
end
|
366
|
+
|
367
|
+
# No longer allow a user to contribute to the wiki.
|
368
|
+
# @param user [User] the user to remove
|
369
|
+
def remove_wiki_contributor(user)
|
370
|
+
remove_relationship(type: 'wikicontributor', name: user.name)
|
371
|
+
end
|
372
|
+
|
373
|
+
# Ban a user from contributing to the wiki.
|
374
|
+
# @param user [User] the user to ban
|
375
|
+
# @param params [Hash] additional options to supply with the request
|
376
|
+
# @option params [String] :ban_reason the reason for the ban (not sure this matters)
|
377
|
+
# @option params [String] :note a note that only moderators can see
|
378
|
+
# @option params [Integer] :duration the number of days to ban the user (if temporary)
|
379
|
+
def ban_wiki_contributor(user, **params)
|
380
|
+
add_relationship(type: 'wikibanned', name: user.name, **params)
|
381
|
+
end
|
382
|
+
|
383
|
+
# No longer ban a user from contributing to the wiki.
|
384
|
+
# @param user [User] the user to unban
|
385
|
+
def unban_wiki_contributor(user)
|
386
|
+
remove_relationship(type: 'wikibanned', name: user.name)
|
387
|
+
end
|
388
|
+
|
296
389
|
private
|
297
390
|
|
391
|
+
def default_loader
|
392
|
+
@client.get("/r/#{@attributes.fetch(:display_name)}/about").body[:data]
|
393
|
+
end
|
394
|
+
|
298
395
|
def add_relationship(**params)
|
299
|
-
# FIXME: add public methods
|
300
396
|
@client.post("/r/#{get_attribute(:display_name)}/api/friend", params)
|
301
397
|
end
|
302
398
|
|
data/lib/redd/models/user.rb
CHANGED
@@ -9,20 +9,20 @@ module Redd
|
|
9
9
|
class User < LazyModel
|
10
10
|
include Messageable
|
11
11
|
|
12
|
-
# Make a User from their name.
|
13
|
-
# @option hash [String] :name the user's name
|
14
|
-
# @return [User]
|
15
|
-
def self.from_response(client, hash)
|
16
|
-
name = hash.fetch(:name)
|
17
|
-
new(client, hash) { |c| c.get("/user/#{name}/about").body[:data] }
|
18
|
-
end
|
19
|
-
|
20
12
|
# Create a User from their name.
|
21
13
|
# @param client [APIClient] the api client to initialize the object with
|
22
14
|
# @param id [String] the username
|
23
15
|
# @return [User]
|
24
16
|
def self.from_id(client, id)
|
25
|
-
|
17
|
+
new(client, name: id)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Unblock a previously blocked user.
|
21
|
+
# @param me [User] (optional) the person doing the unblocking
|
22
|
+
def unblock(me: nil)
|
23
|
+
my_id = 't2_' + (me.is_a?(User) ? user.id : @client.get('/api/v1/me').body[:id])
|
24
|
+
# Talk about an unintuitive endpoint
|
25
|
+
@client.post('/api/unfriend', container: my_id, name: get_attribute(:name), type: 'enemy')
|
26
26
|
end
|
27
27
|
|
28
28
|
# Compose a message to the moderators of a subreddit.
|
@@ -81,6 +81,18 @@ module Redd
|
|
81
81
|
%i(overview submitted comments liked disliked hidden saved gilded).each do |type|
|
82
82
|
define_method(type) { |**params| listing(type, **params) }
|
83
83
|
end
|
84
|
+
|
85
|
+
# Gift a redditor reddit gold.
|
86
|
+
# @param months [Integer] the number of months of gold to gift
|
87
|
+
def gift_gold(months: 1)
|
88
|
+
@client.post("/api/v1/gold/give/#{get_attribute(:name)}", months: months)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def default_loader
|
94
|
+
@client.get("/user/#{@attributes.fetch(:name)}/about").body[:data]
|
95
|
+
end
|
84
96
|
end
|
85
97
|
end
|
86
98
|
end
|
@@ -6,18 +6,15 @@ module Redd
|
|
6
6
|
module Models
|
7
7
|
# A reddit user.
|
8
8
|
class WikiPage < LazyModel
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
sr_name = hash[:subreddit].display_name
|
17
|
-
new(client, hash) { |c| c.get("/r/#{sr_name}/wiki/#{title}").body[:data] }
|
18
|
-
else
|
19
|
-
new(client, hash) { |c| c.get("/wiki/#{title}").body[:data] }
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_loader
|
12
|
+
title = @attributes.fetch(:title)
|
13
|
+
if @attributes.key?(:subreddit)
|
14
|
+
sr_name = attributes[:subreddit].display_name
|
15
|
+
return @client.get("/r/#{sr_name}/wiki/#{title}").body[:data]
|
20
16
|
end
|
17
|
+
@client.get("/wiki/#{title}").body[:data]
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|