ruqqus 1.0.0 → 1.1.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 +4 -4
- data/.gitignore +4 -1
- data/CHANGELOG.md +24 -1
- data/Gemfile +1 -1
- data/README.md +152 -23
- data/Rakefile +1 -2
- data/TODO.md +27 -0
- data/exe/ruqqus-oauth +98 -0
- data/lib/ruqqus.rb +55 -72
- data/lib/ruqqus/client.rb +474 -0
- data/lib/ruqqus/routes.rb +68 -0
- data/lib/ruqqus/token.rb +148 -0
- data/lib/ruqqus/types.rb +11 -0
- data/lib/ruqqus/{badge.rb → types/badge.rb} +0 -0
- data/lib/ruqqus/types/comment.rb +38 -0
- data/lib/ruqqus/{guild.rb → types/guild.rb} +0 -0
- data/lib/ruqqus/{item_base.rb → types/item_base.rb} +4 -2
- data/lib/ruqqus/{post.rb → types/post.rb} +0 -33
- data/lib/ruqqus/{submission.rb → types/submission.rb} +5 -20
- data/lib/ruqqus/{title.rb → types/title.rb} +0 -0
- data/lib/ruqqus/{user.rb → types/user.rb} +0 -3
- data/lib/ruqqus/version.rb +1 -1
- data/ruqqus.gemspec +4 -2
- metadata +48 -15
- data/lib/ruqqus/comment.rb +0 -61
@@ -0,0 +1,474 @@
|
|
1
|
+
require_relative 'version'
|
2
|
+
|
3
|
+
module Ruqqus
|
4
|
+
|
5
|
+
##
|
6
|
+
# Implements interacting with the Ruqqus API as a user, such as login, posting, account management, etc.
|
7
|
+
#noinspection RubyTooManyMethodsInspection
|
8
|
+
class Client
|
9
|
+
|
10
|
+
##
|
11
|
+
# The user-agent the client identified itself as.
|
12
|
+
USER_AGENT = "ruqqus-ruby/#{Ruqqus::VERSION} (efreed09@gmail.com)".freeze
|
13
|
+
|
14
|
+
##
|
15
|
+
# A collection of valid scopes that can be authorized.
|
16
|
+
SCOPES = %i(identity create read update delete vote guildmaster).freeze
|
17
|
+
|
18
|
+
##
|
19
|
+
# A set of HTTP headers that will be included with every request.
|
20
|
+
DEFAULT_HEADERS = { 'User-Agent': USER_AGENT, 'Accept': 'application/json', 'Content-Type': 'application/json' }.freeze
|
21
|
+
|
22
|
+
##
|
23
|
+
# @return [Token] the OAuth2 token that grants the client authentication.
|
24
|
+
attr_reader :token
|
25
|
+
|
26
|
+
##
|
27
|
+
# @!attribute [r] identity
|
28
|
+
# @return [User] the authenticated user this client is performing actions as.
|
29
|
+
|
30
|
+
##
|
31
|
+
# Creates a new instance of the {Client} class.
|
32
|
+
#
|
33
|
+
# @param token [Token] a valid access token to authorize the client.
|
34
|
+
def initialize(token)
|
35
|
+
@token = token || raise(ArgumentError, 'token cannot be nil')
|
36
|
+
@session = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
# @!group Object Querying
|
40
|
+
|
41
|
+
##
|
42
|
+
# Retrieves the {User} with the specified username.
|
43
|
+
#
|
44
|
+
# @param username [String] the username of the Ruqqus account to retrieve.
|
45
|
+
#
|
46
|
+
# @return [User] the requested {User}.
|
47
|
+
#
|
48
|
+
# @raise [ArgumentError] when `username` is `nil` or value does match the {VALID_USERNAME} regular expression.
|
49
|
+
# @raise [Error] thrown when user account does not exist.
|
50
|
+
def user(username)
|
51
|
+
raise(ArgumentError, 'username cannot be nil') unless username
|
52
|
+
raise(ArgumentError, 'invalid username') unless VALID_USERNAME.match?(username)
|
53
|
+
User.from_json(http_get("#{Routes::USER}#{username}"))
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Retrieves the {Guild} with the specified name.
|
58
|
+
#
|
59
|
+
# @param guild_name [String] the name of the Ruqqus guild to retrieve.
|
60
|
+
#
|
61
|
+
# @return [Guild] the requested {Guild}.
|
62
|
+
#
|
63
|
+
# @raise [ArgumentError] when `guild_name` is `nil` or value does match the {VALID_GUILD} regular expression.
|
64
|
+
# @raise [Error] thrown when guild does not exist.
|
65
|
+
def guild(guild_name)
|
66
|
+
raise(ArgumentError, 'guild_name cannot be nil') unless guild_name
|
67
|
+
raise(ArgumentError, 'invalid guild name') unless VALID_GUILD.match?(guild_name)
|
68
|
+
Guild.from_json(http_get("#{Routes::GUILD}#{guild_name}"))
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Retrieves the {Post} with the specified name.
|
73
|
+
#
|
74
|
+
# @param post_id [String] the ID of the post to retrieve.
|
75
|
+
#
|
76
|
+
# @return [Post] the requested {Post}.
|
77
|
+
#
|
78
|
+
# @raise [ArgumentError] when `post_id` is `nil` or value does match the {VALID_POST} regular expression.
|
79
|
+
# @raise [Error] thrown when a post with the specified ID does not exist.
|
80
|
+
def post(post_id)
|
81
|
+
raise(ArgumentError, 'post_id cannot be nil') unless post_id
|
82
|
+
raise(ArgumentError, 'invalid post ID') unless VALID_POST.match?(post_id)
|
83
|
+
Post.from_json(http_get("#{Routes::POST}#{post_id}"))
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Retrieves the {Comment} with the specified name.
|
88
|
+
#
|
89
|
+
# @param comment_id [String] the ID of the comment to retrieve.
|
90
|
+
#
|
91
|
+
# @return [Comment] the requested {Comment}.
|
92
|
+
#
|
93
|
+
# @raise [ArgumentError] when `comment_id` is `nil` or value does match the {VALID_POST} regular expression.
|
94
|
+
# @raise [Error] when a comment with the specified ID does not exist.
|
95
|
+
def comment(comment_id)
|
96
|
+
raise(ArgumentError, 'comment_id cannot be nil') unless comment_id
|
97
|
+
raise(ArgumentError, 'invalid comment ID') unless VALID_POST.match?(comment_id)
|
98
|
+
Comment.from_json(http_get("#{Routes::COMMENT}#{comment_id}"))
|
99
|
+
end
|
100
|
+
|
101
|
+
# @!endgroup Object Querying
|
102
|
+
|
103
|
+
# @!group Commenting
|
104
|
+
|
105
|
+
##
|
106
|
+
# Submits a new comment on a post.
|
107
|
+
#
|
108
|
+
# @param body [String] the text content of the post (supports Markdown)
|
109
|
+
# @param post [Post,String] a {Post} instance or the unique ID of a post.
|
110
|
+
# @param comment [Comment,String] a {Comment} with the post to reply under, or `nil` to reply directly to the post.
|
111
|
+
#
|
112
|
+
# @return [Comment?] the comment that was submitted, or `nil` if an error occurred.
|
113
|
+
#
|
114
|
+
# @note This method is restricted to 6/minute, and will fail when that limit is exceeded.
|
115
|
+
def comment_create(body, post, comment = nil)
|
116
|
+
pid = post.to_s
|
117
|
+
parent = comment ? 't3_' + comment.to_s : 't2_' + pid
|
118
|
+
comment_submit(parent, pid, body)
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Submits a new comment on a post.
|
123
|
+
#
|
124
|
+
# @param body [String] the text content of the comment (supports Markdown)
|
125
|
+
# @param comment [Comment,String] a {Comment} instance or the unique ID of a comment.
|
126
|
+
#
|
127
|
+
# @return [Comment?] the comment that was submitted, or `nil` if an error occurred.
|
128
|
+
#
|
129
|
+
# @note This method is restricted to 6/minute, and will fail when that limit is exceeded.
|
130
|
+
def comment_reply(body, comment)
|
131
|
+
if comment.is_a?(Comment)
|
132
|
+
comment_submit(comment.full_name, comment.post_id, body)
|
133
|
+
else
|
134
|
+
comment = self.comment(comment.to_s)
|
135
|
+
comment_submit(comment.full_name, comment.post_id, body)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# Deletes an existing comment.
|
141
|
+
#
|
142
|
+
# @param comment [Comment,String] a {Comment} instance, or the unique ID of the comment to delete.
|
143
|
+
#
|
144
|
+
# @return [Boolean] `true` if deletion completed without error, otherwise `false`.
|
145
|
+
def comment_delete(comment)
|
146
|
+
id = comment.is_a?(Comment) ? comment.id : comment.sub(/^t3_/, '')
|
147
|
+
url = "#{Routes::API_BASE}/delete/comment/#{id}"
|
148
|
+
http_post(url).empty? rescue false
|
149
|
+
end
|
150
|
+
|
151
|
+
# @!endgroup Commenting
|
152
|
+
|
153
|
+
# @!group Posting
|
154
|
+
|
155
|
+
##
|
156
|
+
# Creates a new post on Ruqqus as the current user.
|
157
|
+
#
|
158
|
+
# @param guild [Guild,String] a {Guild} instance or the name of the guild to post to.
|
159
|
+
# @param title [String] the title of the post to create.
|
160
|
+
# @param body [String?] the text body of the post, which can be `nil` if supplying URL or image upload.
|
161
|
+
# @param opts [Hash] The options hash to specify a link or image to upload.
|
162
|
+
# @option opts [String] :image (nil) the path to an image file to upload.
|
163
|
+
# @option opts [String] :url (nil) a URL to share with the post.
|
164
|
+
# @option opts [String] :imgur_client (nil) an Imgur client ID to automatically share images via Imgur instead of
|
165
|
+
# direct upload.
|
166
|
+
#
|
167
|
+
# @return [Post?] the newly created {Post} instance, or `nil` if an error occurred.
|
168
|
+
# @note This method is restricted to 6/minute, and will fail when that limit is exceeded.
|
169
|
+
def post_create(guild, title, body = nil, **opts)
|
170
|
+
name = guild.is_a?(Guild) ? guild.name : guild.strip.sub(/^\+/, '')
|
171
|
+
raise(ArgumentError, 'invalid guild name') unless Ruqqus::VALID_GUILD.match?(name)
|
172
|
+
raise(ArgumentError, 'title cannot be nil or empty') unless title && !title.empty?
|
173
|
+
params = { title: title, board: name, body: body }
|
174
|
+
|
175
|
+
if opts[:image]
|
176
|
+
if opts[:imgur_client]
|
177
|
+
params[:url] = Ruqqus.imgur_upload(opts[:imgur_client], opts[:image])
|
178
|
+
else
|
179
|
+
params[:file] = File.new(opts[:image])
|
180
|
+
end
|
181
|
+
elsif opts[:url]
|
182
|
+
raise(ArgumentError, 'invalid URI') unless URI.regexp =~ opts[:url]
|
183
|
+
params[:url] = opts[:url]
|
184
|
+
end
|
185
|
+
|
186
|
+
if [params[:body], params[:image], params[:url]].none?
|
187
|
+
raise(ArgumentError, 'text body cannot be nil or empty without URL or image') if body.nil? || body.empty?
|
188
|
+
end
|
189
|
+
Post.from_json(http_post(Routes::SUBMIT, params)) rescue nil
|
190
|
+
end
|
191
|
+
|
192
|
+
# @!endgroup Posting
|
193
|
+
|
194
|
+
# @!group Voting
|
195
|
+
|
196
|
+
##
|
197
|
+
# Places a vote on a post.
|
198
|
+
#
|
199
|
+
# @param post [Post,String] a {Post} instance, or the unique ID of a post.
|
200
|
+
# @param value [Integer] the vote value to place, either `-1`, `0`, or `1`.
|
201
|
+
#
|
202
|
+
# @return [Boolean] `true` if vote was placed successfully, otherwise `false`.
|
203
|
+
def vote_post(post, value = 1)
|
204
|
+
submit_vote(post.to_s, value, 'https://ruqqus.com/api/v1/vote/post/')
|
205
|
+
end
|
206
|
+
|
207
|
+
##
|
208
|
+
# Places a vote on a comment.
|
209
|
+
#
|
210
|
+
# @param comment [Comment,String] a {Comment} instance, or the unique ID of a comment.
|
211
|
+
# @param value [Integer] the vote value to place, either `-1`, `0`, or `1`.
|
212
|
+
#
|
213
|
+
# @return [Boolean] `true` if vote was placed successfully, otherwise `false`.
|
214
|
+
def vote_comment(comment, value = 1)
|
215
|
+
submit_vote(comment.to_s, value, 'https://ruqqus.com/api/v1/vote/comment/')
|
216
|
+
end
|
217
|
+
|
218
|
+
# @!endgroup Voting
|
219
|
+
|
220
|
+
# @!group Object Enumeration
|
221
|
+
|
222
|
+
##
|
223
|
+
# Enumerates through each post of a user, yielding each to a block.
|
224
|
+
#
|
225
|
+
# @param user [User,String] a {User} instance or the name of the account to query.
|
226
|
+
# @yieldparam post [Post] yields a {Post} to the block.
|
227
|
+
# @return [self]
|
228
|
+
# @raise [LocalJumpError] when a block is not supplied to the method.
|
229
|
+
# @note An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at
|
230
|
+
# these intervals is an expected behavior.
|
231
|
+
def each_user_post(user)
|
232
|
+
raise(LocalJumpError, 'block required') unless block_given?
|
233
|
+
each_submission(user, Post, 'listing') { |obj| yield obj }
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Enumerates through each comment of a user, yielding each to a block.
|
238
|
+
#
|
239
|
+
# @param user [User,String] a {User} instance or the name of the account to query.
|
240
|
+
# @yieldparam comment [Comment] yields a {Comment} to the block.
|
241
|
+
# @return [self]
|
242
|
+
# @raise [LocalJumpError] when a block is not supplied to the method.
|
243
|
+
# @note An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at
|
244
|
+
# these intervals is an expected behavior.
|
245
|
+
def each_user_comment(user)
|
246
|
+
raise(LocalJumpError, 'block required') unless block_given?
|
247
|
+
each_submission(user, Comment, 'comments') { |obj| yield obj }
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# Enumerates through each post in the specified guild, and yields each one to a block.
|
252
|
+
#
|
253
|
+
# @param sort [Symbol] a symbol to determine the sorting method, valid values include `:trending`, `:subs`, `:new`.
|
254
|
+
# @yieldparam guild [Guild] yields a {Guild} to the block.
|
255
|
+
# @return [self]
|
256
|
+
# @raise [LocalJumpError] when a block is not supplied to the method.
|
257
|
+
# @note An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at
|
258
|
+
# these intervals is an expected behavior.
|
259
|
+
def each_guild(sort = :subs)
|
260
|
+
raise(LocalJumpError, 'block required') unless block_given?
|
261
|
+
|
262
|
+
page = 1
|
263
|
+
loop do
|
264
|
+
params = { sort: sort, page: page }
|
265
|
+
json = http_get(Routes::GUILDS, headers(params: params))
|
266
|
+
break if json[:error]
|
267
|
+
json[:data].each { |hash| yield Guild.from_json(hash) }
|
268
|
+
break if json[:data].size < 25
|
269
|
+
page += 1
|
270
|
+
end
|
271
|
+
self
|
272
|
+
end
|
273
|
+
|
274
|
+
##
|
275
|
+
# Enumerates through each post in a guild, yielding each to a block.
|
276
|
+
#
|
277
|
+
# @param guild [Guild,String] a {Guild} instance, or the name of the guild to query.
|
278
|
+
# @param opts [Hash] the options hash.
|
279
|
+
# @option opts [Symbol] :sort (:new) Valid: `:new`, `:top`, `:hot`, `:activity`, `:disputed`
|
280
|
+
# @option opts [Symbol] :filter (:all) Valid: `:all`, `:day`, `:week`, `:month`, `:year`
|
281
|
+
#
|
282
|
+
# @yieldparam post [Post] yields a {Post} to the block.
|
283
|
+
# @return [self]
|
284
|
+
# @raise [LocalJumpError] when a block is not supplied to the method.
|
285
|
+
# @note An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at
|
286
|
+
# these intervals is an expected behavior.
|
287
|
+
def each_guild_post(guild, **opts)
|
288
|
+
raise(LocalJumpError, 'block required') unless block_given?
|
289
|
+
name = guild.to_s
|
290
|
+
raise(ArgumentError, 'invalid guild name') unless Ruqqus::VALID_GUILD.match?(name)
|
291
|
+
|
292
|
+
sort = opts[:sort] || :new
|
293
|
+
filter = opts[:filter] || :all
|
294
|
+
|
295
|
+
page = 1
|
296
|
+
loop do
|
297
|
+
params = { page: page, sort: sort, t: filter }
|
298
|
+
json = http_get("#{Routes::GUILD}#{name}/listing", headers(params: params))
|
299
|
+
break if json[:error]
|
300
|
+
|
301
|
+
json[:data].each { |hash| yield Post.from_json(hash) }
|
302
|
+
break if json[:data].size < 25
|
303
|
+
page += 1
|
304
|
+
end
|
305
|
+
|
306
|
+
self
|
307
|
+
end
|
308
|
+
|
309
|
+
##
|
310
|
+
# Enumerates through every post on Ruqqus, yielding each post to a block.
|
311
|
+
#
|
312
|
+
# @param opts [Hash] the options hash.
|
313
|
+
# @option opts [Symbol] :sort (:new) Valid: `:new`, `:top`, `:hot`, `:activity`, `:disputed`
|
314
|
+
# @option opts [Symbol] :filter (:all) Valid: `:all`, `:day`, `:week`, `:month`, `:year`
|
315
|
+
#
|
316
|
+
# @yieldparam post [Post] yields a post to the block.
|
317
|
+
# @return [self]
|
318
|
+
# @raise [LocalJumpError] when a block is not supplied to the method.
|
319
|
+
# @note An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at
|
320
|
+
# these intervals is an expected behavior.
|
321
|
+
def each_post(**opts)
|
322
|
+
raise(LocalJumpError, 'block required') unless block_given?
|
323
|
+
|
324
|
+
sort = opts[:sort] || :new
|
325
|
+
filter = opts[:filter] || :all
|
326
|
+
|
327
|
+
page = 1
|
328
|
+
loop do
|
329
|
+
params = { page: page, sort: sort, t: filter }
|
330
|
+
json = http_get(Routes::ALL_LISTINGS, headers(params: params))
|
331
|
+
break if json[:error]
|
332
|
+
json[:data].each { |hash| yield Post.from_json(hash) }
|
333
|
+
break if json[:data].size < 25
|
334
|
+
page += 1
|
335
|
+
end
|
336
|
+
self
|
337
|
+
end
|
338
|
+
|
339
|
+
##
|
340
|
+
# Enumerates through every post on the "front page", yielding each post to a block.
|
341
|
+
#
|
342
|
+
# @yieldparam post [Post] yields a {Post} to the block.
|
343
|
+
#
|
344
|
+
# @return [self]
|
345
|
+
# @note The front page uses a unique algorithm that is essentially "hot", but for guilds the user is subscribed to.
|
346
|
+
def each_home_post
|
347
|
+
raise(LocalJumpError, 'block required') unless block_given?
|
348
|
+
page = 1
|
349
|
+
loop do
|
350
|
+
json = http_get(Routes::FRONT_PAGE, headers(params: { page: page }))
|
351
|
+
break if json[:error]
|
352
|
+
json[:data].each { |hash| yield Post.from_json(hash) }
|
353
|
+
break if json[:data].size < 25
|
354
|
+
page += 1
|
355
|
+
end
|
356
|
+
self
|
357
|
+
end
|
358
|
+
|
359
|
+
# @!endgroup Object Enumeration
|
360
|
+
|
361
|
+
def identity
|
362
|
+
@me ||= User.from_json(http_get(Routes::IDENTITY))
|
363
|
+
end
|
364
|
+
|
365
|
+
private
|
366
|
+
|
367
|
+
##
|
368
|
+
# @api private
|
369
|
+
# Places a vote on a comment or post.
|
370
|
+
#
|
371
|
+
# @param id [String] the ID of a post or comment.
|
372
|
+
# @param value [Integer] the vote to place, between -1 and 1.
|
373
|
+
# @param route [String] the endpoint of the vote method to invoke.
|
374
|
+
#
|
375
|
+
# @return [Boolean] `true` if vote was placed successfully, otherwise `false`.
|
376
|
+
def submit_vote(id, value, route)
|
377
|
+
raise(Ruqqus::Error, 'invalid ID') unless Ruqqus::VALID_POST.match?(id)
|
378
|
+
amount = [-1, [1, value.to_i].min].max
|
379
|
+
!!http_post("#{route}#{id}/#{amount}")[:error] rescue false
|
380
|
+
end
|
381
|
+
|
382
|
+
##
|
383
|
+
# @api private
|
384
|
+
# Retrieves the HTTP headers for API calls.
|
385
|
+
#
|
386
|
+
# @param opts [Hash] the options hash to include any additional parameters.
|
387
|
+
#
|
388
|
+
# @return [Hash<Symbol, Sting>] a hash containing the header parameters.
|
389
|
+
def headers(**opts)
|
390
|
+
hash = DEFAULT_HEADERS.merge({ Authorization: "#{@token.type} #{@token.access_token}" })
|
391
|
+
opts[:cookies] = { session: @session } if @session
|
392
|
+
hash.merge(opts)
|
393
|
+
end
|
394
|
+
|
395
|
+
##
|
396
|
+
# @api private
|
397
|
+
# Submits a new comment.
|
398
|
+
#
|
399
|
+
# @param parent [String] the full name of a post or comment to reply under. (i.e. `t2_`, `t3_`, etc.)
|
400
|
+
# @param pid [String] the unique ID of the parent post to comment within.
|
401
|
+
# @param body [String] the text body of the comment.
|
402
|
+
#
|
403
|
+
# @return [Comment] the newly submitted comment.
|
404
|
+
def comment_submit(parent, pid, body)
|
405
|
+
raise(ArgumentError, 'body cannot be nil or empty') unless body && !body.empty?
|
406
|
+
params = { submission: pid, parent_fullname: parent, body: body }
|
407
|
+
Comment.from_json(http_post(Routes::COMMENT, params)) rescue nil
|
408
|
+
end
|
409
|
+
|
410
|
+
##
|
411
|
+
# @api private
|
412
|
+
# Enumerates over each page of posts/comments for a user, and returns the deserialized objects.
|
413
|
+
#
|
414
|
+
# @param user [User,String] a {User} instance or the name of the account to query.
|
415
|
+
# @param klass [Class] the type of object to return, must implement `.from_json`.
|
416
|
+
# @param route [String] the final API route for the endpoint, either `"listing"` or "comments"`
|
417
|
+
#
|
418
|
+
# @return [self]
|
419
|
+
def each_submission(user, klass, route)
|
420
|
+
|
421
|
+
username = user.is_a?(User) ? user.username : user.to_s
|
422
|
+
raise(Ruqqus::Error, 'invalid username') unless VALID_USERNAME.match?(username)
|
423
|
+
|
424
|
+
page = 1
|
425
|
+
loop do
|
426
|
+
url = "#{Routes::USER}#{username}/#{route}"
|
427
|
+
json = http_get(url, headers(params: { page: page }))
|
428
|
+
break if json[:error]
|
429
|
+
|
430
|
+
json[:data].each { |hash| yield klass.from_json(hash) }
|
431
|
+
break if json[:data].size < 25
|
432
|
+
page += 1
|
433
|
+
end
|
434
|
+
self
|
435
|
+
end
|
436
|
+
|
437
|
+
##
|
438
|
+
# @api private
|
439
|
+
# Creates and sends a GET request and returns the response as a JSON hash.
|
440
|
+
#
|
441
|
+
# @param uri [String] the endpoint to invoke.
|
442
|
+
# @param header [Hash] a set of headers to send, or `nil` to use the default headers.
|
443
|
+
#
|
444
|
+
# @return [Hash] the response deserialized into a JSON hash.
|
445
|
+
# @see http_post
|
446
|
+
def http_get(uri, header = nil)
|
447
|
+
@token.refresh if @token && @token.expired?
|
448
|
+
header ||= headers
|
449
|
+
response = RestClient.get(uri.chomp('/'), header)
|
450
|
+
@session = response.cookies['session_ruqqus'] if response.cookies['session_ruqqus']
|
451
|
+
raise(Ruqqus::Error, 'HTTP request failed') if response.code < 200 || response.code >= 300
|
452
|
+
JSON.parse(response, symbolize_names: response.body)
|
453
|
+
end
|
454
|
+
|
455
|
+
##
|
456
|
+
# @api private
|
457
|
+
# Creates and sends a POST request and returns the response as a JSON hash.
|
458
|
+
#
|
459
|
+
# @param uri [String] the endpoint to invoke.
|
460
|
+
# @param params [Hash] a hash of parameters that will be sent with the request.
|
461
|
+
# @param header [Hash] a set of headers to send, or `nil` to use the default headers.
|
462
|
+
#
|
463
|
+
# @return [Hash] the response deserialized into a JSON hash.
|
464
|
+
# @see http_get
|
465
|
+
def http_post(uri, params = {}, header = nil)
|
466
|
+
@token.refresh if @token && @token.expired?
|
467
|
+
header ||= headers
|
468
|
+
response = RestClient.post(uri.chomp('/'), params, header)
|
469
|
+
@session = response.cookies['session_ruqqus'] if response.cookies['session_ruqqus']
|
470
|
+
raise(Ruqqus::Error, 'HTTP request failed') if response.code < 200 || response.code >= 300
|
471
|
+
JSON.parse(response, symbolize_names: response.body)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|