redd 0.8.1 → 0.8.2
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.
- 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
|