spinels-redd 0.9.0
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 +7 -0
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/ci.yml +52 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.rubocop.yml +29 -0
- data/CONTRIBUTING.md +63 -0
- data/Gemfile +6 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +119 -0
- data/Rakefile +12 -0
- data/TODO.md +423 -0
- data/bin/console +127 -0
- data/bin/guard +2 -0
- data/bin/setup +8 -0
- data/docs/guides/.keep +0 -0
- data/docs/tutorials/creating-bots-with-redd.md +101 -0
- data/docs/tutorials/creating-webapps-with-redd.md +124 -0
- data/docs/tutorials/make-a-grammar-bot.md +5 -0
- data/docs/tutorials.md +7 -0
- data/lib/redd/api_client.rb +116 -0
- data/lib/redd/assist/delete_badly_scoring.rb +64 -0
- data/lib/redd/auth_strategies/auth_strategy.rb +68 -0
- data/lib/redd/auth_strategies/script.rb +35 -0
- data/lib/redd/auth_strategies/userless.rb +29 -0
- data/lib/redd/auth_strategies/web.rb +36 -0
- data/lib/redd/client.rb +91 -0
- data/lib/redd/errors.rb +65 -0
- data/lib/redd/middleware.rb +125 -0
- data/lib/redd/models/access.rb +54 -0
- data/lib/redd/models/comment.rb +229 -0
- data/lib/redd/models/front_page.rb +55 -0
- data/lib/redd/models/gildable.rb +13 -0
- data/lib/redd/models/inboxable.rb +33 -0
- data/lib/redd/models/listing.rb +52 -0
- data/lib/redd/models/live_thread.rb +133 -0
- data/lib/redd/models/live_update.rb +46 -0
- data/lib/redd/models/messageable.rb +20 -0
- data/lib/redd/models/mod_action.rb +59 -0
- data/lib/redd/models/model.rb +23 -0
- data/lib/redd/models/moderatable.rb +46 -0
- data/lib/redd/models/modmail.rb +61 -0
- data/lib/redd/models/modmail_conversation.rb +154 -0
- data/lib/redd/models/modmail_message.rb +35 -0
- data/lib/redd/models/more_comments.rb +96 -0
- data/lib/redd/models/multireddit.rb +104 -0
- data/lib/redd/models/paginated_listing.rb +124 -0
- data/lib/redd/models/postable.rb +83 -0
- data/lib/redd/models/private_message.rb +105 -0
- data/lib/redd/models/replyable.rb +16 -0
- data/lib/redd/models/reportable.rb +14 -0
- data/lib/redd/models/searchable.rb +35 -0
- data/lib/redd/models/self.rb +17 -0
- data/lib/redd/models/session.rb +198 -0
- data/lib/redd/models/submission.rb +405 -0
- data/lib/redd/models/subreddit.rb +670 -0
- data/lib/redd/models/trophy.rb +34 -0
- data/lib/redd/models/user.rb +239 -0
- data/lib/redd/models/wiki_page.rb +56 -0
- data/lib/redd/utilities/error_handler.rb +73 -0
- data/lib/redd/utilities/rate_limiter.rb +21 -0
- data/lib/redd/utilities/unmarshaller.rb +70 -0
- data/lib/redd/version.rb +5 -0
- data/lib/redd.rb +129 -0
- data/lib/spinels-redd.rb +3 -0
- data/logo.png +0 -0
- data/spinels-redd.gemspec +39 -0
- metadata +298 -0
@@ -0,0 +1,198 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
require_relative 'searchable'
|
5
|
+
|
6
|
+
module Redd
|
7
|
+
module Models
|
8
|
+
# The starter class.
|
9
|
+
class Session < Model
|
10
|
+
include Searchable
|
11
|
+
|
12
|
+
# @return [User] the logged-in user
|
13
|
+
def me
|
14
|
+
@me ||= Self.new(client)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [FrontPage] the user's front page
|
18
|
+
def front_page
|
19
|
+
@front_page ||= FrontPage.new(client)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Modmail] the new modmail
|
23
|
+
def modmail
|
24
|
+
@modmail ||= Modmail.new(client)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [LiveThread] the live thread
|
28
|
+
def live_thread(id)
|
29
|
+
LiveThread.new(client, id: id)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Hash] a breakdown of karma over subreddits
|
33
|
+
def karma_breakdown
|
34
|
+
client.get('/api/v1/me/karma').body[:data]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get a (lazily loaded) reddit user by their name.
|
38
|
+
# @param name [String] the username
|
39
|
+
# @return [User]
|
40
|
+
def user(name)
|
41
|
+
User.new(client, name: name)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns whether a username is available.
|
45
|
+
# @param username [String] the username to check
|
46
|
+
# @return [Boolean] whether the username is available
|
47
|
+
def username_available?(username)
|
48
|
+
client.get('/api/username_available', user: username).body
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get a (lazily loaded) subreddit by its name.
|
52
|
+
# @param display_name [String] the subreddit's display name
|
53
|
+
# @return [Subreddit]
|
54
|
+
def subreddit(display_name)
|
55
|
+
Subreddit.new(client, display_name: display_name)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Array<Multireddit>] array of multireddits belonging to the user
|
59
|
+
def my_multis
|
60
|
+
client.get('/api/multi/mine').body.map { |m| client.unmarshal(m) }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get a (lazily loaded) multi by its path.
|
64
|
+
# @param path [String] the multi's path, surrounded by a leading and trailing /
|
65
|
+
# @return [Multireddit]
|
66
|
+
def multi(path)
|
67
|
+
Multireddit.new(client, path: path)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get submissions or comments by their fullnames.
|
71
|
+
# @param fullnames [String, Array<String>] one or an array of fullnames (e.g. t3_abc1234)
|
72
|
+
# @return [Listing<Submission, Comment>]
|
73
|
+
# @deprecated Try the lazier {#from_fullnames} instead.
|
74
|
+
def from_ids(*fullnames)
|
75
|
+
client.model(:get, '/api/info', id: fullnames.join(','))
|
76
|
+
end
|
77
|
+
|
78
|
+
# Create lazily-loaded objects from their fullnames (e.g. t1_abc123).
|
79
|
+
# @param fullnames [String] fullname for a submission, comment, or subreddit.
|
80
|
+
# @return [Array<Submission, Comment, User, Subreddit>]
|
81
|
+
def from_fullnames(*fullnames) # rubocop:disable Metrics/MethodLength
|
82
|
+
fullnames.map do |name|
|
83
|
+
if name.start_with?('t1_')
|
84
|
+
Comment.new(client, name: name)
|
85
|
+
elsif name.start_with?('t3_')
|
86
|
+
Submission.new(client, name: name)
|
87
|
+
elsif name.start_with?('t5_')
|
88
|
+
Subreddit.new(client, name: name)
|
89
|
+
else
|
90
|
+
raise "unknown fullname #{name}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get submissions or comments by their fullnames.
|
96
|
+
# @param url [String] the object's url
|
97
|
+
# @return [Submission, Comment, nil] the object, or nil if not found
|
98
|
+
def from_url(url)
|
99
|
+
client.model(:get, '/api/info', url: url).first
|
100
|
+
end
|
101
|
+
|
102
|
+
# Return a listing of the user's inbox (including comment replies and private messages).
|
103
|
+
#
|
104
|
+
# @param category ['inbox', 'unread', 'sent', 'moderator', 'messages', 'comments',
|
105
|
+
# 'selfreply', 'mentions'] the category of messages to view
|
106
|
+
# @param mark [Boolean] whether to remove the orangered from the user's inbox
|
107
|
+
# @param params [Hash] a list of optional params to send with the request
|
108
|
+
# @option params [String] :after return results after the given fullname
|
109
|
+
# @option params [String] :before return results before the given fullname
|
110
|
+
# @option params [Integer] :count (0) the number of items already seen in the listing
|
111
|
+
# @option params [1..100] :limit (25) the maximum number of things to return
|
112
|
+
# @return [Listing<Comment, PrivateMessage>]
|
113
|
+
def my_messages(category: 'inbox', mark: false, **params)
|
114
|
+
client.model(:get, "/message/#{category}.json", params.merge(mark: mark))
|
115
|
+
end
|
116
|
+
|
117
|
+
# Mark all messages as read.
|
118
|
+
def read_all_messages
|
119
|
+
client.post('/api/read_all_messages')
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return [Hash] the user's preferences
|
123
|
+
def my_preferences
|
124
|
+
client.get('/api/v1/me/prefs').body
|
125
|
+
end
|
126
|
+
|
127
|
+
# Edit the user's preferences.
|
128
|
+
# @param new_prefs [Hash] the changed preferences
|
129
|
+
# @return [Hash] the new preferences
|
130
|
+
# @see #my_preferences
|
131
|
+
def edit_preferences(new_prefs = {})
|
132
|
+
client.request(
|
133
|
+
:patch, '/api/v1/me/prefs',
|
134
|
+
headers: { 'Content-Type' => 'application/json' },
|
135
|
+
body: JSON.generate(new_prefs)
|
136
|
+
).body
|
137
|
+
end
|
138
|
+
|
139
|
+
# @return [Array<User>] the logged-in user's friends
|
140
|
+
def friends
|
141
|
+
client.get('/api/v1/me/friends').body[:data][:children].map do |h|
|
142
|
+
User.new(client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# @return [Array<User>] users blocked by the logged-in user
|
147
|
+
def blocked
|
148
|
+
client.get('/prefs/blocked').body[:data][:children].map do |h|
|
149
|
+
User.new(client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# @return [Array<User>] users trusted by the logged-in user
|
154
|
+
def trusted
|
155
|
+
client.get('/prefs/trusted').body[:data][:children].map do |h|
|
156
|
+
User.new(client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# @return [Array<String>] a list of categories the user's items are saved in
|
161
|
+
def saved_categories
|
162
|
+
client.get('/api/saved_categories').body
|
163
|
+
end
|
164
|
+
|
165
|
+
# Return a listing of the user's subreddits.
|
166
|
+
#
|
167
|
+
# @param type ['subscriber', 'contributor', 'moderator'] the type of subreddits
|
168
|
+
# @param params [Hash] a list of optional params to send with the request
|
169
|
+
# @option params [String] :after return results after the given fullname
|
170
|
+
# @option params [String] :before return results before the given fullname
|
171
|
+
# @option params [Integer] :count (0) the number of items already seen in the listing
|
172
|
+
# @option params [1..100] :limit (25) the maximum number of things to return
|
173
|
+
# @return [Listing<Subreddit>]
|
174
|
+
def my_subreddits(type, **params)
|
175
|
+
client.model(:get, "/subreddits/mine/#{type}", params)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Return trending subreddits.
|
179
|
+
# @return [Hash]
|
180
|
+
# @example
|
181
|
+
# session.trending_subreddits
|
182
|
+
# => {
|
183
|
+
# "subreddit_names": [
|
184
|
+
# "AskLibertarians",
|
185
|
+
# "OpTicGaming",
|
186
|
+
# "Cuphead",
|
187
|
+
# "AlmostParkour",
|
188
|
+
# "TheGoodPlace"
|
189
|
+
# ],
|
190
|
+
# "comment_count": 176,
|
191
|
+
# "comment_url": "/r/trendingsubreddits/comments/73dkin/trending_subreddits_for_..."
|
192
|
+
# }
|
193
|
+
def trending_subreddits
|
194
|
+
client.get('/api/trending_subreddits').body
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,405 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
require_relative 'gildable'
|
5
|
+
require_relative 'moderatable'
|
6
|
+
require_relative 'postable'
|
7
|
+
require_relative 'replyable'
|
8
|
+
require_relative 'reportable'
|
9
|
+
|
10
|
+
require_relative 'user'
|
11
|
+
require_relative 'subreddit'
|
12
|
+
|
13
|
+
module Redd
|
14
|
+
module Models
|
15
|
+
# A text or link post.
|
16
|
+
class Submission < Model # rubocop:disable Metrics/ClassLength
|
17
|
+
include Gildable
|
18
|
+
include Moderatable
|
19
|
+
include Postable
|
20
|
+
include Replyable
|
21
|
+
include Reportable
|
22
|
+
|
23
|
+
# @return [String] the sort order
|
24
|
+
def sort_order
|
25
|
+
exists_locally?(:sort_order) ? read_attribute(:sort_order) : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set the sort order of the comments and reload the comments.
|
29
|
+
# @param new_order [:confidence, :top, :controversial, :old, :qa] the sort order
|
30
|
+
def update_sort_order(new_order)
|
31
|
+
return self if new_order == read_attribute(:sort_order)
|
32
|
+
|
33
|
+
write_attribute(:sort_order, new_order)
|
34
|
+
reload
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get all submissions for the same url.
|
38
|
+
# @param params [Hash] A list of optional params to send with the request.
|
39
|
+
# @option params [String] :after return results after the given fullname
|
40
|
+
# @option params [String] :before return results before the given fullname
|
41
|
+
# @option params [Integer] :count (0) the number of items already seen in the listing
|
42
|
+
# @option params [1..100] :limit (25) the maximum number of things to return
|
43
|
+
# @return [Listing<Submission>]
|
44
|
+
def duplicates(**params)
|
45
|
+
client.unmarshal(client.get("/duplicates/#{read_attribute(:id)}", params).body[1])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Mark the link as "Not Suitable For Work".
|
49
|
+
def mark_as_nsfw
|
50
|
+
client.get('/api/marknsfw', id: read_attribute(:name))
|
51
|
+
end
|
52
|
+
|
53
|
+
# No longer mark the link as "Not Suitable For Work".
|
54
|
+
def unmark_as_nsfw
|
55
|
+
client.get('/api/unmarknsfw', id: read_attribute(:name))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Mark the link as a spoiler.
|
59
|
+
def mark_as_spoiler
|
60
|
+
client.get('/api/spoiler', id: read_attribute(:name))
|
61
|
+
end
|
62
|
+
|
63
|
+
# No longer mark the link as a spoiler.
|
64
|
+
def unmark_as_spoiler
|
65
|
+
client.get('/api/unspoiler', id: read_attribute(:name))
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set the submission to "contest mode" (comments are randomly sorted)
|
69
|
+
def enable_contest_mode
|
70
|
+
client.post('/api/set_contest_mode', id: read_attribute(:name), state: true)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Disable the "contest mode".
|
74
|
+
def disable_contest_mode
|
75
|
+
client.post('/api/set_contest_mode', id: read_attribute(:name), state: false)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Set the submission as the sticky post of the subreddit.
|
79
|
+
# @param slot [1, 2] which "slot" to place the sticky on
|
80
|
+
def make_sticky(slot: nil)
|
81
|
+
client.post('/api/set_subreddit_sticky', id: read_attribute(:name), num: slot, state: true)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Unsticky the post from the subreddit.
|
85
|
+
def remove_sticky
|
86
|
+
client.post('/api/set_subreddit_sticky', id: read_attribute(:name), state: false)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Prevent users from commenting on the link (and hide it as well).
|
90
|
+
def lock
|
91
|
+
client.post('/api/lock', id: read_attribute(:name))
|
92
|
+
end
|
93
|
+
|
94
|
+
# Allow users to comment on the link again.
|
95
|
+
def unlock
|
96
|
+
client.post('/api/unlock', id: read_attribute(:name))
|
97
|
+
end
|
98
|
+
|
99
|
+
# Set the suggested sort order for comments for all users.
|
100
|
+
# @param suggested ['blank', 'confidence', 'top', 'new', 'controversial', 'old', 'random',
|
101
|
+
# 'qa', 'live'] the sort type
|
102
|
+
def set_suggested_sort(suggested) # rubocop:disable Naming/AccessorMethodName
|
103
|
+
client.post('/api/set_suggested_sort', id: read_attribute(:name), sort: suggested)
|
104
|
+
end
|
105
|
+
|
106
|
+
# @!attribute [r] sort_order
|
107
|
+
# @return [Symbol] the comment sort order
|
108
|
+
property :sort_order, :nil
|
109
|
+
|
110
|
+
# @!attribute [r] comments
|
111
|
+
# @return [Array<Comment>] the comment tree
|
112
|
+
property :comments, :nil, with: ->(l) { Listing.new(client, l) if l }
|
113
|
+
|
114
|
+
# @!attribute [r] domain
|
115
|
+
# @return [String] the domain name of the link (or self.subreddit_name)
|
116
|
+
property :domain
|
117
|
+
|
118
|
+
# @!attribute [r] approved_at
|
119
|
+
# @return [Time, nil] when the submission was last approved
|
120
|
+
property :approved_at, from: :approved_at_utc, with: ->(t) { Time.at(t) if t }
|
121
|
+
|
122
|
+
# @!attribute [r] banned_by
|
123
|
+
# @return [String] not sure what this does
|
124
|
+
property :banned_by
|
125
|
+
|
126
|
+
# @!attribute [r] media_embed
|
127
|
+
# @return [Hash] media embed properties
|
128
|
+
property :media_embed
|
129
|
+
|
130
|
+
# @!attribute [r] subreddit
|
131
|
+
# @return [Subreddit] the subreddit the post belongs to.
|
132
|
+
property :subreddit, with: ->(n) { Subreddit.new(client, display_name: n) }
|
133
|
+
|
134
|
+
# @!attribute [r] selftext_html
|
135
|
+
# @return [String, nil] the html-rendered self text, can be nil if link
|
136
|
+
property :selftext_html
|
137
|
+
|
138
|
+
# @!attribute [r] selftext
|
139
|
+
# @return [String] the self text contents
|
140
|
+
property :selftext
|
141
|
+
|
142
|
+
# @!attribute [r] upvoted?
|
143
|
+
# @return [Boolean, nil] whether the user upvoted/downvoted this post
|
144
|
+
property :upvoted?, from: :likes
|
145
|
+
|
146
|
+
# @!attribute [r] suggested_sort
|
147
|
+
# @return [String, nil] the suggested sort
|
148
|
+
property :suggested_sort
|
149
|
+
|
150
|
+
# @!attribute [r] user_reports
|
151
|
+
# @return [Array<String>] user reports
|
152
|
+
property :user_reports
|
153
|
+
|
154
|
+
# @!attribute [r] secure_media
|
155
|
+
# @return [Hash, nil] secure media details
|
156
|
+
property :secure_media
|
157
|
+
|
158
|
+
# @!attribute [r] link_flair_text
|
159
|
+
# @return [String] the link flair text
|
160
|
+
property :link_flair_text
|
161
|
+
|
162
|
+
# @!attribute [r] link_flair_css_class
|
163
|
+
# @return [String] the link flair css class
|
164
|
+
property :link_flair_css_class
|
165
|
+
|
166
|
+
# @!attribute [r] id
|
167
|
+
# @return [String] the submission id
|
168
|
+
property :id
|
169
|
+
|
170
|
+
# @!attribute [r] banned_at
|
171
|
+
# @return [Time, nil] the time the post was banned
|
172
|
+
property :banned_at, from: :banned_at_utc, with: ->(t) { Time.at(t) if t }
|
173
|
+
|
174
|
+
# @!attribute [r] view_count
|
175
|
+
# @return [Integer, nil] the view count
|
176
|
+
property :view_count
|
177
|
+
|
178
|
+
# @!attribute [r] archived?
|
179
|
+
# @return [Boolean] whether the post is archived
|
180
|
+
property :archived?, from: :archived
|
181
|
+
|
182
|
+
# @!attribute [r] clicked?
|
183
|
+
# @return [Boolean] whether the post was clicked
|
184
|
+
property :clicked?, from: :clicked
|
185
|
+
|
186
|
+
# @!attribute [r] report_reasons
|
187
|
+
# @return [Object] i think it's an array of strings?
|
188
|
+
property :report_reasons
|
189
|
+
|
190
|
+
# @!attribute [r] title
|
191
|
+
# @return [String] the post title
|
192
|
+
property :title
|
193
|
+
|
194
|
+
# @!attribute [r] num_crossposts
|
195
|
+
# @return [Integer] the number of crossposts made to other subreddits
|
196
|
+
property :num_crossposts
|
197
|
+
|
198
|
+
# @!attribute [r] saved?
|
199
|
+
# @return [String] whether the post was saved by the logged-in user
|
200
|
+
property :saved?, from: :saved
|
201
|
+
|
202
|
+
# @!attribute [r] can_mod_post?
|
203
|
+
# @return [Boolean] whether you can post as a mod, i think
|
204
|
+
property :can_mod_post?, from: :can_mod_post
|
205
|
+
|
206
|
+
# @!attribute [r] crosspostable?
|
207
|
+
# @return [Boolean] whether the post can be crossposted
|
208
|
+
property :crosspostable?, from: :is_crosspostable
|
209
|
+
|
210
|
+
# @!attribute [r] pinned?
|
211
|
+
# @return [Boolean] whether the post is pinned
|
212
|
+
property :pinned?, from: :pinned
|
213
|
+
|
214
|
+
# @!attribute [r] score
|
215
|
+
# @return [Integer] the post's score
|
216
|
+
property :score
|
217
|
+
|
218
|
+
# @!attribute [r] approved_by
|
219
|
+
# @return [Object] the person that approved this post (not sure about the schema)
|
220
|
+
property :approved_by
|
221
|
+
|
222
|
+
# @!attribute [r] over_18?
|
223
|
+
# @return [Boolean] whether the post is marked as over 18
|
224
|
+
property :over_18?, from: :over_18
|
225
|
+
|
226
|
+
# @!attribute [r] hidden?
|
227
|
+
# @return [Boolean] whether the logged-in user hid the post
|
228
|
+
property :hidden?, from: :hidden
|
229
|
+
|
230
|
+
# @!attribute [r] preview
|
231
|
+
# @return [Hash] preview details
|
232
|
+
property :preview
|
233
|
+
|
234
|
+
# @!attribute [r] comment_count
|
235
|
+
# @return [Integer] the post's comment count
|
236
|
+
property :comment_count, from: :num_comments
|
237
|
+
|
238
|
+
# @!attribute [r] thumbnail
|
239
|
+
# @return [String] the thumbnail url
|
240
|
+
property :thumbnail
|
241
|
+
|
242
|
+
# @!attribute [r] thumbnail_height
|
243
|
+
# @return [Integer] thumbnail height
|
244
|
+
property :thumbnail_height
|
245
|
+
|
246
|
+
# @!attribute [r] score_hidden?
|
247
|
+
# @return [Boolean] whether the score is hidden
|
248
|
+
property :score_hidden?, from: :hide_score
|
249
|
+
|
250
|
+
# @!attribute [r] edited
|
251
|
+
# @return [Time, false] the time of the last edit
|
252
|
+
property :edited, with: ->(t) { Time.at(t) if t }
|
253
|
+
|
254
|
+
# @!attribute [r] author_flair_text
|
255
|
+
# @return [String] the author flair text
|
256
|
+
property :author_flair_text
|
257
|
+
|
258
|
+
# @!attribute [r] author_flair_css_class
|
259
|
+
# @return [String] the author flair css class
|
260
|
+
property :author_flair_css_class
|
261
|
+
|
262
|
+
# @!attribute [r] contest_mode_enabled?
|
263
|
+
# @return [Boolean] whether contest mode is turned on
|
264
|
+
property :contest_mode_enabled?, from: :contest_mode
|
265
|
+
|
266
|
+
# @!attribute [r] gilded
|
267
|
+
# @return [Integer] the number of times the post was gilded
|
268
|
+
property :gilded
|
269
|
+
|
270
|
+
# @!attribute [r] locked?
|
271
|
+
# @return [Boolean] whether the post is locked
|
272
|
+
property :locked?, from: :locked
|
273
|
+
|
274
|
+
# @!attribute [r] ups
|
275
|
+
# @return [Integer] upvote count
|
276
|
+
# @deprecated this doesn't return the raw upvote count - use {#score} instead
|
277
|
+
property :ups
|
278
|
+
|
279
|
+
# @!attribute [r] downs
|
280
|
+
# @return [Integer] downvote count
|
281
|
+
# @deprecated this always returns zero - use {#score} instead
|
282
|
+
property :downs
|
283
|
+
|
284
|
+
# @!attribute [r] brand_safe?
|
285
|
+
# @return [Boolean] whether the post is marked as brand safe
|
286
|
+
property :brand_safe?, from: :brand_safe
|
287
|
+
|
288
|
+
# @!attribute [r] secure_media_embed
|
289
|
+
# @return [Hash] secure media embed details
|
290
|
+
property :secure_media_embed
|
291
|
+
|
292
|
+
# @!attribute [r] removal_reason
|
293
|
+
# @return [String] the removal reason
|
294
|
+
property :removal_reason
|
295
|
+
|
296
|
+
# @!attribute [r] post_hint
|
297
|
+
# @return [String] a hint at what the link should contain
|
298
|
+
property :post_hint
|
299
|
+
|
300
|
+
# @!attribute [r] can_gild?
|
301
|
+
# @return [Boolean] whether the user can gild this post
|
302
|
+
property :can_gild?, from: :can_gild
|
303
|
+
|
304
|
+
# @!attribute [r] parent_whitelist_status
|
305
|
+
# @return [String] ad-related whitelist stuff
|
306
|
+
property :parent_whitelist_status
|
307
|
+
|
308
|
+
# @!attribute [r] name
|
309
|
+
# @return [String] the fullname (i.e. t3_xxxxxx)
|
310
|
+
property :name
|
311
|
+
|
312
|
+
# @!attribute [r] spoiler?
|
313
|
+
# @return [Boolean] whether the post was marked as a spoiler
|
314
|
+
property :spoiler?, from: :spoiler
|
315
|
+
|
316
|
+
# @!attribute [r] permalink
|
317
|
+
# @return [String] the **relative** url permalink
|
318
|
+
property :permalink
|
319
|
+
|
320
|
+
# @!attribute [r] report_count
|
321
|
+
# @return [Integer] the number of reports
|
322
|
+
property :report_count, from: :num_reports
|
323
|
+
|
324
|
+
# @!attribute [r] whitelist_status
|
325
|
+
# @return [String] ad-related whitelist stuff
|
326
|
+
property :whitelist_status
|
327
|
+
|
328
|
+
# @!attribute [r] stickied?
|
329
|
+
# @return [Boolean] whether the post was stickied
|
330
|
+
property :stickied?, from: :stickied
|
331
|
+
|
332
|
+
# @!attribute [r] url
|
333
|
+
# @return [String] the link url
|
334
|
+
property :url
|
335
|
+
|
336
|
+
# @!attribute [r] quarantined?
|
337
|
+
# @return [Boolean] whether the post has been quarantined
|
338
|
+
property :quarantined?, from: :quarantine
|
339
|
+
|
340
|
+
# @!attribute [r] author
|
341
|
+
# @return [User] the post author
|
342
|
+
property :author, with: ->(n) { User.new(client, name: n) }
|
343
|
+
|
344
|
+
# @!attribute [r] created_at
|
345
|
+
# @return [Time] creation time
|
346
|
+
property :created_at, from: :created_utc, with: ->(t) { Time.at(t) }
|
347
|
+
|
348
|
+
# @!attribute [r] subreddit_name_prefixed
|
349
|
+
# @return [String] r/[subreddit name]
|
350
|
+
property :subreddit_name_prefixed,
|
351
|
+
default: -> { "r/#{read_attribute(:subreddit).display_name}" }
|
352
|
+
|
353
|
+
# @!attribute [r] distinguished?
|
354
|
+
# @return [Boolean] whether the post is distinguished
|
355
|
+
property :distinguished?, from: :distinguished
|
356
|
+
|
357
|
+
# @!attribute [r] media
|
358
|
+
# @return [Hash] media details
|
359
|
+
property :media
|
360
|
+
|
361
|
+
# @!attribute [r] upvote_ratio
|
362
|
+
# @return [Float] the upvote ratio (ups/downs)
|
363
|
+
property :upvote_ratio
|
364
|
+
|
365
|
+
# @!attribute [r] mod_reports
|
366
|
+
# @return [Array] moderator reports
|
367
|
+
property :mod_reports
|
368
|
+
|
369
|
+
# @!attribute [r] self?
|
370
|
+
# @return [Boolean] whether the post is a self post
|
371
|
+
property :self?, from: :is_self
|
372
|
+
|
373
|
+
# @!attribute [r] visited?
|
374
|
+
# @return [Boolean] whether the post was visited
|
375
|
+
property :visited?, from: :visited
|
376
|
+
|
377
|
+
# @!attribute [r] subreddit_type
|
378
|
+
# @return [String] the subreddit's type
|
379
|
+
property :subreddit_type
|
380
|
+
|
381
|
+
# @!attribute [r] video?
|
382
|
+
# @return [Boolean] whether the post is probably a video
|
383
|
+
property :video, from: :is_video
|
384
|
+
|
385
|
+
private
|
386
|
+
|
387
|
+
def lazer_reload # rubocop:disable Metrics/AbcSize
|
388
|
+
fully_loaded!
|
389
|
+
|
390
|
+
# Ensure we have the link's id.
|
391
|
+
id = exists_locally?(:id) ? read_attribute(:id) : read_attribute(:name).sub('t3_', '')
|
392
|
+
|
393
|
+
# If a specific sort order was requested, provide it.
|
394
|
+
params = {}
|
395
|
+
params[:sort] = read_attribute(:sort_order) if exists_locally?(:sort_order)
|
396
|
+
|
397
|
+
# `response` is a pair (2-element array):
|
398
|
+
# - response[0] is a one-item listing containing the submission
|
399
|
+
# - response[1] is listing of comments
|
400
|
+
response = client.get("/comments/#{id}", params).body
|
401
|
+
response[0][:data][:children][0][:data].merge(comments: response[1][:data])
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|