Class: Ruqqus::Client
- Inherits:
-
Object
- Object
- Ruqqus::Client
- Defined in:
- lib/ruqqus/client.rb
Overview
Implements interacting with the Ruqqus API as a user, such as login, posting, account management, etc. noinspection RubyTooManyMethodsInspection
Constant Summary collapse
- USER_AGENT =
The user-agent the client identified itself as.
"ruqqus-ruby/#{Ruqqus::VERSION}".freeze
- SCOPES =
A collection of valid scopes that can be authorized.
:identity
- See your username.:create
- Save posts and comments as you:read
- View Ruqqus as you, including private or restricted content:update
- Edit your posts and comments:delete
- Delete your posts and comments:vote
- Cast votes as you:guildmaster
- Perform Guildmaster actions
%i(identity create read update delete vote guildmaster).freeze
- DEFAULT_HEADERS =
A set of HTTP headers that will be included with every request.
{ 'User-Agent': USER_AGENT, 'Accept': 'application/json', 'Content-Type': 'application/json' }.freeze
Instance Attribute Summary collapse
-
#identity ⇒ User
readonly
The authenticated user this client is performing actions as.
-
#token ⇒ Token
The OAuth2 token that grants the client authentication.
Object Querying collapse
-
#comment(comment_id) ⇒ Comment
Retrieves the Comment with the specified name.
-
#guild(guild_name) ⇒ Guild
Retrieves the Guild with the specified name.
-
#post(post_id) ⇒ Post
Retrieves the Post with the specified name.
-
#user(username) ⇒ User
Retrieves the User with the specified username.
Commenting collapse
-
#comment_create(body, post, comment = nil) ⇒ Comment?
Submits a new comment on a post.
-
#comment_delete(comment) ⇒ Boolean
Deletes an existing comment.
-
#comment_reply(body, comment) ⇒ Comment?
Submits a new comment on a post.
-
#post_delete(post) ⇒ Boolean
Deletes an existing post.
Posting collapse
-
#post_create(guild, title, body = nil, **opts) ⇒ Post?
Creates a new post on Ruqqus as the current user.
Voting collapse
-
#vote_comment(comment, value = 1) ⇒ Boolean
Places a vote on a comment.
-
#vote_post(post, value = 1) ⇒ Boolean
Places a vote on a post.
Object Enumeration collapse
-
#each_guild(sort = :subs) {|guild| ... } ⇒ self
Enumerates through each post in the specified guild, and yields each one to a block.
-
#each_guild_comment(guild) {|yields| ... } ⇒ self
Enumerates through each comment in a guild, yielding each to a block.
-
#each_guild_post(guild, **opts) {|post| ... } ⇒ self
Enumerates through each post in a guild, yielding each to a block.
-
#each_home_post {|post| ... } ⇒ self
Enumerates through every post on the "front page", yielding each post to a block.
-
#each_post(**opts) {|post| ... } ⇒ self
Enumerates through every post on Ruqqus, yielding each post to a block.
-
#each_post_comment(post) {|yields| ... } ⇒ self
Enumerates through each comment in a guild, yielding each to a block.
-
#each_user_comment(user) {|comment| ... } ⇒ self
Enumerates through each comment of a user, yielding each to a block.
-
#each_user_post(user) {|post| ... } ⇒ self
Enumerates through each post of a user, yielding each to a block.
Instance Method Summary collapse
-
#initialize(client_id, client_secret, token) ⇒ Client
constructor
A new instance of Client.
- #token_refreshed(&block) ⇒ void
Constructor Details
#initialize(client_id, client_secret, token) ⇒ Client #initialize(client_id, client_secret, code) ⇒ Client
Returns a new instance of Client.
50 51 52 53 54 55 56 57 |
# File 'lib/ruqqus/client.rb', line 50 def initialize(client_id, client_secret, token) @client_id = client_id || raise(ArgumentError, 'client ID cannot be nil') @client_secret = client_secret || raise(ArgumentError, 'client secret cannot be nil') @token = token.is_a?(Token) ? token : Token.new(client_id, client_secret, token.to_s) @token.refresh(client_id, client_secret) @session = nil end |
Instance Attribute Details
#identity ⇒ User (readonly)
Returns the authenticated user this client is performing actions as.
|
# File 'lib/ruqqus/client.rb', line 34
|
#token ⇒ Token
Returns the OAuth2 token that grants the client authentication.
|
# File 'lib/ruqqus/client.rb', line 30
|
Instance Method Details
#comment(comment_id) ⇒ Comment
Retrieves the Ruqqus::Comment with the specified name.
121 122 123 124 125 |
# File 'lib/ruqqus/client.rb', line 121 def comment(comment_id) raise(ArgumentError, 'comment_id cannot be nil') unless comment_id raise(ArgumentError, 'invalid comment ID') unless VALID_POST.match?(comment_id) Comment.from_json(http_get("#{Routes::COMMENT}#{comment_id}")) end |
#comment_create(body, post, comment = nil) ⇒ Comment?
This method is restricted to 6/minute, and will fail when that limit is exceeded.
Submits a new comment on a post.
141 142 143 144 145 |
# File 'lib/ruqqus/client.rb', line 141 def comment_create(body, post, comment = nil) pid = post.to_s parent = comment ? 't3_' + comment.to_s : 't2_' + pid comment_submit(parent, pid, body) end |
#comment_delete(comment) ⇒ Boolean
Deletes an existing comment.
171 172 173 174 175 |
# File 'lib/ruqqus/client.rb', line 171 def comment_delete(comment) id = comment.is_a?(Comment) ? comment.id : comment.sub(/^t3_/, '') url = "#{Routes::API_BASE}/delete/comment/#{id}" http_post(url).empty? rescue false end |
#comment_reply(body, comment) ⇒ Comment?
This method is restricted to 6/minute, and will fail when that limit is exceeded.
Submits a new comment on a post.
156 157 158 159 160 161 162 163 |
# File 'lib/ruqqus/client.rb', line 156 def comment_reply(body, comment) if comment.is_a?(Comment) comment_submit(comment.fullname, comment.post_id, body) else comment = self.comment(comment.to_s) comment_submit(comment.fullname, comment.post_id, body) end end |
#each_guild(sort = :subs) {|guild| ... } ⇒ self
An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at these intervals is an expected behavior.
Enumerates through each post in the specified guild, and yields each one to a block.
297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/ruqqus/client.rb', line 297 def each_guild(sort = :subs) raise(LocalJumpError, 'block required') unless block_given? page = 1 loop do params = { sort: sort, page: page } json = http_get(Routes::GUILDS, headers(params: params)) break if json[:error] json[:data].each { |hash| yield Guild.from_json(hash) } break if json[:data].size < 25 page += 1 end self end |
#each_guild_comment(guild) {|yields| ... } ⇒ self
Enumerates through each comment in a guild, yielding each to a block.
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/ruqqus/client.rb', line 355 def each_guild_comment(guild) raise(LocalJumpError, 'block required') unless block_given? name = guild.to_s raise(ArgumentError, 'invalid guild name') unless Ruqqus::VALID_GUILD.match?(name) page = 1 loop do params = { page: page } json = http_get("#{Routes::GUILD}#{name}/comments", headers(params: params)) break if json[:error] json[:data].each { |hash| yield Comment.from_json(hash) } break if json[:data].size < 25 page += 1 end self end |
#each_guild_post(guild, **opts) {|post| ... } ⇒ self
An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at these intervals is an expected behavior.
Enumerates through each post in a guild, yielding each to a block.
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/ruqqus/client.rb', line 325 def each_guild_post(guild, **opts) raise(LocalJumpError, 'block required') unless block_given? name = guild.to_s raise(ArgumentError, 'invalid guild name') unless Ruqqus::VALID_GUILD.match?(name) sort = opts[:sort] || :new filter = opts[:filter] || :all page = 1 loop do params = { page: page, sort: sort, t: filter } json = http_get("#{Routes::GUILD}#{name}/listing", headers(params: params)) break if json[:error] json[:data].each { |hash| yield Post.from_json(hash) } break if json[:data].size < 25 page += 1 end self end |
#each_home_post {|post| ... } ⇒ self
The front page uses a unique algorithm that is essentially "hot", but for guilds the user is subscribed to.
Enumerates through every post on the "front page", yielding each post to a block.
432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/ruqqus/client.rb', line 432 def each_home_post raise(LocalJumpError, 'block required') unless block_given? page = 1 loop do json = http_get(Routes::FRONT_PAGE, headers(params: { page: page })) break if json[:error] json[:data].each { |hash| yield Post.from_json(hash) } break if json[:data].size < 25 page += 1 end self end |
#each_post(**opts) {|post| ... } ⇒ self
An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at these intervals is an expected behavior.
Enumerates through every post on Ruqqus, yielding each post to a block.
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'lib/ruqqus/client.rb', line 407 def each_post(**opts) raise(LocalJumpError, 'block required') unless block_given? sort = opts[:sort] || :new filter = opts[:filter] || :all page = 1 loop do params = { page: page, sort: sort, t: filter } json = http_get(Routes::ALL_LISTINGS, headers(params: params)) break if json[:error] json[:data].each { |hash| yield Post.from_json(hash) } break if json[:data].size < 25 page += 1 end self end |
#each_post_comment(post) {|yields| ... } ⇒ self
This method is very inefficient, as it the underlying API does not yet implement it, therefore each comment in the entire guild must be searched through.
Enumerates through each comment in a guild, yielding each to a block.
384 385 386 387 388 389 390 391 392 393 |
# File 'lib/ruqqus/client.rb', line 384 def each_post_comment(post) # TODO: This is extremely inefficient, but will have to do until it gets implemented in the API raise(LocalJumpError, 'block required') unless block_given? post = self.post(post) unless post.is_a?(Post) each_guild_comment(post.guild_name) do |comment| next unless comment.post_id == post.id yield comment end self end |
#each_user_comment(user) {|comment| ... } ⇒ self
An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at these intervals is an expected behavior.
Enumerates through each comment of a user, yielding each to a block.
283 284 285 286 |
# File 'lib/ruqqus/client.rb', line 283 def each_user_comment(user) raise(LocalJumpError, 'block required') unless block_given? each_submission(user, Comment, 'comments') { |obj| yield obj } end |
#each_user_post(user) {|post| ... } ⇒ self
An API invocation is required for every 25 items that are yielded to the block, so observing brief pauses at these intervals is an expected behavior.
Enumerates through each post of a user, yielding each to a block.
269 270 271 272 |
# File 'lib/ruqqus/client.rb', line 269 def each_user_post(user) raise(LocalJumpError, 'block required') unless block_given? each_submission(user, Post, 'listing') { |obj| yield obj } end |
#guild(guild_name) ⇒ Guild
Retrieves the Guild with the specified name.
91 92 93 94 95 |
# File 'lib/ruqqus/client.rb', line 91 def guild(guild_name) raise(ArgumentError, 'guild_name cannot be nil') unless guild_name raise(ArgumentError, 'invalid guild name') unless VALID_GUILD.match?(guild_name) Guild.from_json(http_get("#{Routes::GUILD}#{guild_name}")) end |
#post(post_id) ⇒ Post
Retrieves the Post with the specified name.
106 107 108 109 110 |
# File 'lib/ruqqus/client.rb', line 106 def post(post_id) raise(ArgumentError, 'post_id cannot be nil') unless post_id raise(ArgumentError, 'invalid post ID') unless VALID_POST.match?(post_id) Post.from_json(http_get("#{Routes::POST}#{post_id}")) end |
#post_create(guild, title, body = nil, **opts) ⇒ Post?
This method is restricted to 6/minute, and will fail when that limit is exceeded.
Creates a new post on Ruqqus as the current user.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/ruqqus/client.rb', line 207 def post_create(guild, title, body = nil, **opts) name = guild.is_a?(Guild) ? guild.name : guild.strip.sub(/^\+/, '') raise(ArgumentError, 'invalid guild name') unless Ruqqus::VALID_GUILD.match?(name) raise(ArgumentError, 'title cannot be nil or empty') unless title && !title.empty? params = { title: title, board: name, body: body } if opts[:image] if opts[:imgur_client] params[:url] = Ruqqus.imgur_upload(opts[:imgur_client], opts[:image]) else params[:file] = File.new(opts[:image]) end elsif opts[:url] raise(ArgumentError, 'invalid URI') unless URI.regexp =~ opts[:url] params[:url] = opts[:url] end if [params[:body], params[:image], params[:url]].none? raise(ArgumentError, 'text body cannot be nil or empty without URL or image') if body.nil? || body.empty? end Post.from_json(http_post(Routes::SUBMIT, params)) rescue nil end |
#post_delete(post) ⇒ Boolean
Deletes an existing post.
183 184 185 186 187 |
# File 'lib/ruqqus/client.rb', line 183 def post_delete(post) id = post.is_a?(Post) ? post.id : post.sub(/^t3_/, '') url = "#{Routes::API_BASE}/delete_post/#{id}" http_post(url).empty? rescue false end |
#token_refreshed {|token| ... } ⇒ void #token_refreshed ⇒ void
This method returns an undefined value.
462 463 464 |
# File 'lib/ruqqus/client.rb', line 462 def token_refreshed(&block) @refreshed = block_given? ? block : nil end |
#user(username) ⇒ User
Retrieves the User with the specified username.
76 77 78 79 80 |
# File 'lib/ruqqus/client.rb', line 76 def user(username) raise(ArgumentError, 'username cannot be nil') unless username raise(ArgumentError, 'invalid username') unless VALID_USERNAME.match?(username) User.from_json(http_get("#{Routes::USER}#{username}")) end |
#vote_comment(comment, value = 1) ⇒ Boolean
Places a vote on a comment.
252 253 254 |
# File 'lib/ruqqus/client.rb', line 252 def vote_comment(comment, value = 1) submit_vote(comment.to_s, value, 'https://ruqqus.com/api/v1/vote/comment/') end |
#vote_post(post, value = 1) ⇒ Boolean
Places a vote on a post.
241 242 243 |
# File 'lib/ruqqus/client.rb', line 241 def vote_post(post, value = 1) submit_vote(post.to_s, value, 'https://ruqqus.com/api/v1/vote/post/') end |