redd 0.8.8 → 0.9.0.pre.1
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/.rubocop.yml +4 -1
- data/CONTRIBUTING.md +63 -0
- data/Guardfile +7 -0
- data/README.md +6 -5
- data/Rakefile +1 -1
- data/TODO.md +423 -0
- data/bin/console +91 -77
- data/bin/guard +2 -0
- data/lib/redd.rb +7 -5
- data/lib/redd/api_client.rb +2 -3
- data/lib/redd/auth_strategies/auth_strategy.rb +7 -2
- data/lib/redd/auth_strategies/script.rb +7 -0
- data/lib/redd/auth_strategies/userless.rb +7 -0
- data/lib/redd/auth_strategies/web.rb +6 -1
- data/lib/redd/client.rb +0 -3
- data/lib/redd/errors.rb +56 -0
- data/lib/redd/middleware.rb +10 -8
- data/lib/redd/models/access.rb +30 -18
- data/lib/redd/models/comment.rb +185 -27
- data/lib/redd/models/front_page.rb +16 -36
- data/lib/redd/models/gildable.rb +1 -1
- data/lib/redd/models/inboxable.rb +13 -3
- data/lib/redd/models/listing.rb +27 -6
- data/lib/redd/models/live_thread.rb +76 -23
- data/lib/redd/models/live_update.rb +46 -0
- data/lib/redd/models/messageable.rb +1 -1
- data/lib/redd/models/mod_action.rb +59 -0
- data/lib/redd/models/model.rb +23 -0
- data/lib/redd/models/moderatable.rb +6 -6
- 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 +29 -5
- data/lib/redd/models/multireddit.rb +63 -20
- data/lib/redd/models/paginated_listing.rb +113 -0
- data/lib/redd/models/postable.rb +11 -13
- data/lib/redd/models/private_message.rb +78 -11
- data/lib/redd/models/replyable.rb +2 -2
- data/lib/redd/models/reportable.rb +14 -0
- data/lib/redd/models/searchable.rb +2 -2
- data/lib/redd/models/self.rb +17 -0
- data/lib/redd/models/session.rb +75 -31
- data/lib/redd/models/submission.rb +309 -56
- data/lib/redd/models/subreddit.rb +330 -103
- data/lib/redd/models/trophy.rb +34 -0
- data/lib/redd/models/user.rb +185 -46
- data/lib/redd/models/wiki_page.rb +37 -16
- data/lib/redd/utilities/error_handler.rb +13 -13
- data/lib/redd/utilities/unmarshaller.rb +7 -5
- data/lib/redd/version.rb +1 -1
- data/redd.gemspec +18 -15
- metadata +82 -16
- data/lib/redd/error.rb +0 -53
- data/lib/redd/models/basic_model.rb +0 -80
- data/lib/redd/models/lazy_model.rb +0 -75
- data/lib/redd/models/mod_mail.rb +0 -142
- data/lib/redd/utilities/stream.rb +0 -61
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
|
5
|
+
module Redd
|
6
|
+
module Models
|
7
|
+
# A user trophy.
|
8
|
+
class Trophy < Model
|
9
|
+
# @!attribute [r] icon_70px
|
10
|
+
# @return [String] the url for a 70x70 thumbnail icon
|
11
|
+
property :icon_70px, from: :icon_70
|
12
|
+
|
13
|
+
# @!attribute [r] icon_40px
|
14
|
+
# @return [String] the url for a 40x40 thumbnail icon
|
15
|
+
property :icon_40px, from: :icon_40
|
16
|
+
|
17
|
+
# @!attribute [r] name
|
18
|
+
# @return [String] the name of the trophy
|
19
|
+
property :name
|
20
|
+
|
21
|
+
# @!attribute [r] id
|
22
|
+
# @return [String] the trophy id
|
23
|
+
property :id
|
24
|
+
|
25
|
+
# @!attribute [r] award_id
|
26
|
+
# @return [String]
|
27
|
+
property :award_id
|
28
|
+
|
29
|
+
# @!attribute [r] description
|
30
|
+
# @return [String] the trophy description
|
31
|
+
property :description
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/redd/models/user.rb
CHANGED
@@ -1,53 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'model'
|
4
4
|
require_relative 'messageable'
|
5
5
|
|
6
6
|
module Redd
|
7
7
|
module Models
|
8
8
|
# A reddit user.
|
9
|
-
class User <
|
9
|
+
class User < Model
|
10
10
|
include Messageable
|
11
11
|
|
12
|
-
# Create a User from their name.
|
13
|
-
# @param client [APIClient] the api client to initialize the object with
|
14
|
-
# @param id [String] the username
|
15
|
-
# @return [User]
|
16
|
-
def self.from_id(client, id)
|
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
|
-
end
|
27
|
-
|
28
|
-
# Compose a message to the moderators of a subreddit.
|
29
|
-
#
|
30
|
-
# @param subject [String] the subject of the message
|
31
|
-
# @param text [String] the message text
|
32
|
-
# @param from [Subreddit, nil] the subreddit to send the message on behalf of
|
33
|
-
def send_message(subject:, text:, from: nil)
|
34
|
-
super(to: get_attribute(:name), subject: subject, text: text, from: from)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Add the user as a friend.
|
38
|
-
# @param note [String] a note for the friend
|
39
|
-
def friend(note = nil)
|
40
|
-
name = get_attribute(:name)
|
41
|
-
body = JSON.generate(note ? { name: name, note: note } : { name: name })
|
42
|
-
@client.request(:put, "/api/v1/me/friends/#{name}", body: body)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Unfriend the user.
|
46
|
-
def unfriend
|
47
|
-
name = get_attribute(:name)
|
48
|
-
@client.request(:delete, "/api/v1/me/friends/#{name}", raw: true, form: { id: name })
|
49
|
-
end
|
50
|
-
|
51
12
|
# Get the appropriate listing.
|
52
13
|
# @param type [:overview, :submitted, :comments, :liked, :disliked, :hidden, :saved, :gilded]
|
53
14
|
# the type of listing to request
|
@@ -65,7 +26,7 @@ module Redd
|
|
65
26
|
# @return [Listing<Submission>]
|
66
27
|
def listing(type, **params)
|
67
28
|
params[:t] = params.delete(:time) if params.key?(:time)
|
68
|
-
|
29
|
+
client.model(:get, "/user/#{read_attribute(:name)}/#{type}.json", params)
|
69
30
|
end
|
70
31
|
|
71
32
|
# @!method overview(**params)
|
@@ -78,20 +39,198 @@ module Redd
|
|
78
39
|
# @!method gilded(**params)
|
79
40
|
#
|
80
41
|
# @see #listing
|
81
|
-
%i
|
42
|
+
%i[overview submitted comments liked disliked hidden saved gilded].each do |type|
|
82
43
|
define_method(type) { |**params| listing(type, **params) }
|
83
44
|
end
|
84
45
|
|
46
|
+
# Compose a message to the moderators of a subreddit.
|
47
|
+
#
|
48
|
+
# @param subject [String] the subject of the message
|
49
|
+
# @param text [String] the message text
|
50
|
+
# @param from [Subreddit, nil] the subreddit to send the message on behalf of
|
51
|
+
def send_message(subject:, text:, from: nil)
|
52
|
+
super(to: read_attribute(:name), subject: subject, text: text, from: from)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Block this user.
|
56
|
+
def block
|
57
|
+
client.post('/api/block_user', account_id: read_attribute(:id))
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Array<Trophy>] this user's trophies
|
61
|
+
def trophies
|
62
|
+
client.get("/api/v1/user/#{read_attribute(:name)}/trophies")
|
63
|
+
.body[:data][:trophies]
|
64
|
+
.map { |t| client.unmarshal(t) }
|
65
|
+
end
|
66
|
+
|
67
|
+
# Unblock a previously blocked user.
|
68
|
+
# @param me [User] (optional) the person doing the unblocking
|
69
|
+
def unblock(me: nil)
|
70
|
+
my_id = 't2_' + (me.is_a?(User) ? user.id : client.get('/api/v1/me').body[:id])
|
71
|
+
# Talk about an unintuitive endpoint
|
72
|
+
client.post('/api/unfriend', container: my_id, name: read_attribute(:name), type: 'enemy')
|
73
|
+
end
|
74
|
+
|
75
|
+
# Add the user as a friend.
|
76
|
+
# @param note [String] a note for the friend
|
77
|
+
def friend(note = nil)
|
78
|
+
name = read_attribute(:name)
|
79
|
+
body = JSON.generate(note ? { name: name, note: note } : { name: name })
|
80
|
+
client.request(:put, "/api/v1/me/friends/#{name}", body: body)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Unfriend the user.
|
84
|
+
def unfriend
|
85
|
+
name = read_attribute(:name)
|
86
|
+
client.request(:delete, "/api/v1/me/friends/#{name}", raw: true, form: { id: name })
|
87
|
+
end
|
88
|
+
|
85
89
|
# Gift a redditor reddit gold.
|
86
90
|
# @param months [Integer] the number of months of gold to gift
|
87
91
|
def gift_gold(months: 1)
|
88
|
-
|
92
|
+
client.post("/api/v1/gold/give/#{read_attribute(:name)}", months: months)
|
89
93
|
end
|
90
94
|
|
95
|
+
# @!attribute [r] name
|
96
|
+
# @return [String] the user's username
|
97
|
+
property :name
|
98
|
+
|
99
|
+
# @!attribute [r] employee?
|
100
|
+
# @return [Boolean] whether the user is a reddit employee
|
101
|
+
property :employee?, from: :is_employee
|
102
|
+
|
103
|
+
# @!attribute [r] features
|
104
|
+
# @return [Hash] a hash of features
|
105
|
+
property :features
|
106
|
+
|
107
|
+
# @!attribute [r] friend?
|
108
|
+
# @return [Boolean] whether the user is your friend
|
109
|
+
property :friend?, from: :is_friend
|
110
|
+
|
111
|
+
# @!attribute [r] no_profanity?
|
112
|
+
# @return [Boolean] whether the user chooses to filter profanity
|
113
|
+
property :no_profanity?, from: :pref_no_profanity
|
114
|
+
|
115
|
+
# @!attribute [r] suspended?
|
116
|
+
# @return [Boolean] whether the user is suspended
|
117
|
+
property :suspended?, from: :is_suspended
|
118
|
+
|
119
|
+
# @!attribute [r] geopopular
|
120
|
+
# @return [String]
|
121
|
+
property :geopopular, from: :pref_geopopular
|
122
|
+
|
123
|
+
# @!attribute [r] subreddit
|
124
|
+
# @return [Subreddit] the user's personal "subreddit"
|
125
|
+
property :subreddit, with: ->(name) { Subreddit.new(client, display_name: name) if name }
|
126
|
+
|
127
|
+
# @!attribute [r] sponsor?
|
128
|
+
# @return [Boolean]
|
129
|
+
property :sponsor?, from: :is_sponsor
|
130
|
+
|
131
|
+
# @!attribute [r] gold_expiration
|
132
|
+
# @return [Time, nil] the time when the user's gold expires
|
133
|
+
property :gold_expiration, with: ->(epoch) { Time.at(epoch) if epoch }
|
134
|
+
|
135
|
+
# @!attribute [r] id
|
136
|
+
# @return [String] the user's base36 id
|
137
|
+
property :id
|
138
|
+
|
139
|
+
# @!attribute [r] profile_image
|
140
|
+
# @return [String] a link to the user's profile image
|
141
|
+
property :profile_image, from: :profile_img
|
142
|
+
|
143
|
+
# @!attribute [r] over_18?
|
144
|
+
# @return [Boolean] whether the user's profile is considered over 18.
|
145
|
+
property :over_18?, from: :profile_over_18
|
146
|
+
|
147
|
+
# @!attribute [r] suspension_expiration
|
148
|
+
# @return [Time, nil] the time when the user's suspension expires
|
149
|
+
property :suspension_expiration, from: :suspension_expiration_utc,
|
150
|
+
with: ->(epoch) { Time.at(epoch) if epoch }
|
151
|
+
|
152
|
+
# @!attribute [r] verified?
|
153
|
+
# @return [Boolean] whether the user is verified (?)
|
154
|
+
property :verified?, from: :verified
|
155
|
+
|
156
|
+
# @!attribute [r] new_modmail_exists?
|
157
|
+
# @return [Boolean] whether the user has mail in the new modmail
|
158
|
+
property :new_modmail_exists?, from: :new_modmail_exists
|
159
|
+
|
160
|
+
# @!attribute [r] over_18?
|
161
|
+
# @return [Boolean] whether the user has indicated they're over 18
|
162
|
+
property :over_18?, from: :over_18
|
163
|
+
|
164
|
+
# @!attribute [r] gold?
|
165
|
+
# @return [Boolean] whether the user currently has gold
|
166
|
+
property :gold?, from: :is_gold
|
167
|
+
|
168
|
+
# @!attribute [r] mod?
|
169
|
+
# @return [Boolean] whether the user is a moderator
|
170
|
+
property :mod?, from: :is_mod
|
171
|
+
|
172
|
+
# @!attribute [r] has_verified_email?
|
173
|
+
# @return [Boolean] whether the user's email has been verified
|
174
|
+
property :has_verified_email?, from: :has_verified_email
|
175
|
+
|
176
|
+
# @!attribute [r] has_mod_mail?
|
177
|
+
# @return [Boolean] whether the user has old-style mod mail
|
178
|
+
property :has_mod_mail?, from: :has_mod_mail
|
179
|
+
|
180
|
+
# @!attribute [r] hidden_from_robots?
|
181
|
+
# @return [Boolean] whether the user chose to hide from Google
|
182
|
+
property :hidden_from_robots?, from: :hide_from_robots
|
183
|
+
|
184
|
+
# @!attribute [r] link_karma
|
185
|
+
# @return [Integer] the user's link karma
|
186
|
+
property :link_karma
|
187
|
+
|
188
|
+
# @!attribute [r] inbox_count
|
189
|
+
# @return [Integer] the number of messages in the user's inbox
|
190
|
+
property :inbox_count
|
191
|
+
|
192
|
+
# @!attribute [r] show_top_karma_subreddits?
|
193
|
+
# @return [Boolean] whether top karma subreddits are shown on the user's page
|
194
|
+
property :show_top_karma_subreddits?, from: :pref_top_karma_subreddits
|
195
|
+
|
196
|
+
# @!attribute [r] has_mail?
|
197
|
+
# @return [Boolean] whether the user has new messages
|
198
|
+
property :has_mail?, from: :has_mail
|
199
|
+
|
200
|
+
# @!attribute [r] show_snoovatar?
|
201
|
+
# @return [Boolean] whether the user's snoovatar is shown
|
202
|
+
property :show_snoovatar?, from: :pref_show_snoovatar
|
203
|
+
|
204
|
+
# @!attribute [r] created_at
|
205
|
+
# @return [Time] the time the user signed up
|
206
|
+
property :created_at, from: :created_utc, with: ->(epoch) { Time.at(epoch) }
|
207
|
+
|
208
|
+
# @!attribute [r] gold_creddits
|
209
|
+
# @return [Integer] the number of gold creddits the user has
|
210
|
+
property :gold_creddits
|
211
|
+
|
212
|
+
# @!attribute [r] in_beta?
|
213
|
+
# @return [Boolean] whether the user is in beta
|
214
|
+
property :in_beta?, from: :in_beta
|
215
|
+
|
216
|
+
# @!attribute [r] comment_karma
|
217
|
+
# @return [Integer] the user's comment karma
|
218
|
+
property :comment_karma
|
219
|
+
|
220
|
+
# @!attribute [r] has_subscribed?
|
221
|
+
# @return [Boolean]
|
222
|
+
property :has_subscribed?, from: :has_subscribed
|
223
|
+
|
91
224
|
private
|
92
225
|
|
93
|
-
def
|
94
|
-
|
226
|
+
def lazer_reload
|
227
|
+
# return load_from_fullname if self[:id] && !self[:name]
|
228
|
+
fully_loaded!
|
229
|
+
client.get("/user/#{read_attribute(:name)}/about").body[:data]
|
230
|
+
end
|
231
|
+
|
232
|
+
def load_from_fullname
|
233
|
+
client.get('/api/user_data_by_account_ids', ids: read_attribute(:id)).body.values.first
|
95
234
|
end
|
96
235
|
end
|
97
236
|
end
|
@@ -1,34 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'model'
|
4
4
|
|
5
5
|
module Redd
|
6
6
|
module Models
|
7
7
|
# A reddit user.
|
8
|
-
class WikiPage <
|
8
|
+
class WikiPage < Model
|
9
9
|
# Edit the wiki page.
|
10
10
|
# @param content [String] the new wiki page contents
|
11
11
|
# @param reason [String, nil] an optional reason for editing the page
|
12
12
|
def edit(content, reason: nil)
|
13
|
-
params = { page:
|
13
|
+
params = { page: read_attribute(:title), content: content }
|
14
14
|
params[:reason] = reason if reason
|
15
|
-
|
15
|
+
client.post("/r/#{read_attribute(:subreddit).display_name}/api/wiki/edit", params)
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
# @!attribute [r] title
|
19
|
+
# @return [String] the page title
|
20
|
+
property :title, :required
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
# @!attribute [r] subreddit
|
23
|
+
# @return [Subreddit] the wiki page's (optional) subreddit
|
24
|
+
property :subreddit, :nil
|
25
|
+
|
26
|
+
# @!attribute [r] may_revise?
|
27
|
+
# @return [Boolean] not sure, whether you're allowed to edit the page?
|
28
|
+
property :may_revise?, from: :may_revise
|
29
|
+
|
30
|
+
# @!attribute [r] revision_date
|
31
|
+
# @return [Time] the time of the last revision
|
32
|
+
property :revision_date, with: ->(t) { Time.at(t) }
|
33
|
+
|
34
|
+
# @!attribute [r] content_md
|
35
|
+
# @return [String] the markdown version of the content
|
36
|
+
property :content_md
|
37
|
+
|
38
|
+
# @!attribute [r] content_html
|
39
|
+
# @return [String] the html version of the content
|
40
|
+
property :content_html
|
41
|
+
|
42
|
+
# @!attribute [r] revision_by
|
43
|
+
# @return [User] the user who made the last revision
|
44
|
+
property :revision_by, with: ->(res) { User.new(client, res[:data]) }
|
45
|
+
|
46
|
+
private
|
28
47
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
48
|
+
def lazer_reload
|
49
|
+
fully_loaded!
|
50
|
+
path = "/wiki/#{read_attribute(:title)}"
|
51
|
+
path = "/r/#{read_attribute(:subreddit).display_name}#{path}" if self[:subreddit]
|
52
|
+
client.get(path).body[:data]
|
32
53
|
end
|
33
54
|
end
|
34
55
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../
|
3
|
+
require_relative '../errors'
|
4
4
|
|
5
5
|
module Redd
|
6
6
|
module Utilities
|
@@ -11,15 +11,15 @@ module Redd
|
|
11
11
|
INSUFFICIENT_SCOPE = 'insufficient_scope'
|
12
12
|
|
13
13
|
HTTP_ERRORS = {
|
14
|
-
400 =>
|
15
|
-
403 =>
|
16
|
-
404 =>
|
17
|
-
429 =>
|
18
|
-
500 =>
|
19
|
-
502 =>
|
20
|
-
503 =>
|
21
|
-
504 =>
|
22
|
-
}
|
14
|
+
400 => Errors::BadRequest,
|
15
|
+
403 => Errors::Forbidden,
|
16
|
+
404 => Errors::NotFound,
|
17
|
+
429 => Errors::TooManyRequests,
|
18
|
+
500 => Errors::ServerError,
|
19
|
+
502 => Errors::ServerError,
|
20
|
+
503 => Errors::ServerError,
|
21
|
+
504 => Errors::ServerError
|
22
|
+
}
|
23
23
|
|
24
24
|
def check_error(res, raw:)
|
25
25
|
# Check for status code-based errors first and return it if we found one.
|
@@ -38,14 +38,14 @@ module Redd
|
|
38
38
|
def invalid_access_error(res)
|
39
39
|
return nil unless res.code == 401 && res.headers[AUTH_HEADER] &&
|
40
40
|
res.headers[AUTH_HEADER].include?(INVALID_TOKEN)
|
41
|
-
InvalidAccess.new(res)
|
41
|
+
Errors::InvalidAccess.new(res)
|
42
42
|
end
|
43
43
|
|
44
44
|
# Deal with an error caused by not having enough the correct scope
|
45
45
|
def insufficient_scope_error(res)
|
46
46
|
return nil unless res.code == 403 && res.headers[AUTH_HEADER] &&
|
47
47
|
res.headers[AUTH_HEADER].include?(INSUFFICIENT_SCOPE)
|
48
|
-
InsufficientScope.new(res)
|
48
|
+
Errors::InsufficientScope.new(res)
|
49
49
|
end
|
50
50
|
|
51
51
|
# Deal with an error signalled by the HTTP response code.
|
@@ -57,7 +57,7 @@ module Redd
|
|
57
57
|
def api_error(res)
|
58
58
|
return nil unless res.body.is_a?(Hash) && res.body[:json] && res.body[:json][:errors] &&
|
59
59
|
!res.body[:json][:errors].empty?
|
60
|
-
APIError.new(res)
|
60
|
+
Errors::APIError.new(res)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -7,17 +7,19 @@ module Redd
|
|
7
7
|
# Contains the mapping from 'kind' strings to classes.
|
8
8
|
# TODO: UserList type!
|
9
9
|
MAPPING = {
|
10
|
+
'Listing' => Models::Listing,
|
10
11
|
't1' => Models::Comment,
|
11
12
|
't2' => Models::User,
|
12
13
|
't3' => Models::Submission,
|
13
14
|
't4' => Models::PrivateMessage,
|
14
15
|
't5' => Models::Subreddit,
|
16
|
+
't6' => Models::Trophy,
|
15
17
|
'more' => Models::MoreComments,
|
16
18
|
'wikipage' => Models::WikiPage,
|
17
|
-
'modaction' => Models::
|
19
|
+
'modaction' => Models::ModAction,
|
18
20
|
'LabeledMulti' => Models::Multireddit,
|
19
|
-
'LiveUpdate' => Models::
|
20
|
-
}
|
21
|
+
'LiveUpdate' => Models::LiveUpdate
|
22
|
+
}
|
21
23
|
|
22
24
|
def initialize(client)
|
23
25
|
@client = client
|
@@ -25,7 +27,7 @@ module Redd
|
|
25
27
|
|
26
28
|
def unmarshal(res)
|
27
29
|
# I'm loving the hell out of this pattern.
|
28
|
-
model = js_listing(res) || js_model(res) ||
|
30
|
+
model = js_listing(res) || js_model(res) || api_model(res)
|
29
31
|
raise "cannot unmarshal: #{res.inspect}" if model.nil?
|
30
32
|
model
|
31
33
|
end
|
@@ -43,7 +45,7 @@ module Redd
|
|
43
45
|
def js_model(res)
|
44
46
|
# FIXME: deprecate this? this shouldn't be happening in the API, so this is better handled
|
45
47
|
# in the respective classes.
|
46
|
-
Models::
|
48
|
+
Models::Model.new(@client, res[:json][:data]) if res[:json] && res[:json][:data]
|
47
49
|
end
|
48
50
|
|
49
51
|
# Unmarshal API-provided listings.
|