redd 0.6.5 → 0.7.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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +34 -33
  3. data/.rspec +3 -4
  4. data/.rubocop.yml +5 -5
  5. data/.travis.yml +9 -7
  6. data/{LICENSE.md → LICENSE.txt} +22 -22
  7. data/README.md +126 -241
  8. data/Rakefile +5 -6
  9. data/{RedditKit.LICENSE.md → RedditKit.LICENSE.txt} +13 -13
  10. data/lib/redd.rb +50 -4
  11. data/lib/redd/access.rb +76 -0
  12. data/lib/redd/clients/base.rb +178 -0
  13. data/lib/redd/clients/base/account.rb +20 -0
  14. data/lib/redd/clients/base/identity.rb +22 -0
  15. data/lib/redd/clients/base/none.rb +27 -0
  16. data/lib/redd/clients/base/privatemessages.rb +28 -0
  17. data/lib/redd/clients/base/read.rb +66 -0
  18. data/lib/redd/clients/base/stream.rb +74 -0
  19. data/lib/redd/clients/base/submit.rb +54 -0
  20. data/lib/redd/clients/base/utilities.rb +80 -0
  21. data/lib/redd/clients/base/wikiread.rb +33 -0
  22. data/lib/redd/clients/installed.rb +55 -0
  23. data/lib/redd/clients/script.rb +37 -0
  24. data/lib/redd/clients/userless.rb +31 -0
  25. data/lib/redd/clients/web.rb +57 -0
  26. data/lib/redd/error.rb +138 -153
  27. data/lib/redd/objects/base.rb +36 -0
  28. data/lib/redd/objects/comment.rb +22 -0
  29. data/lib/redd/objects/listing.rb +29 -0
  30. data/lib/redd/objects/more_comments.rb +10 -0
  31. data/lib/redd/objects/private_message.rb +18 -0
  32. data/lib/redd/objects/submission.rb +72 -0
  33. data/lib/redd/objects/subreddit.rb +152 -0
  34. data/lib/redd/objects/thing.rb +33 -0
  35. data/lib/redd/objects/thing/editable.rb +22 -0
  36. data/lib/redd/objects/thing/hideable.rb +18 -0
  37. data/lib/redd/objects/thing/inboxable.rb +25 -0
  38. data/lib/redd/objects/thing/messageable.rb +34 -0
  39. data/lib/redd/objects/thing/moderatable.rb +43 -0
  40. data/lib/redd/objects/thing/refreshable.rb +14 -0
  41. data/lib/redd/objects/thing/saveable.rb +21 -0
  42. data/lib/redd/objects/thing/votable.rb +33 -0
  43. data/lib/redd/objects/user.rb +52 -0
  44. data/lib/redd/objects/wiki_page.rb +15 -0
  45. data/lib/redd/rate_limit.rb +50 -49
  46. data/lib/redd/response/parse_json.rb +17 -33
  47. data/lib/redd/response/raise_error.rb +16 -25
  48. data/lib/redd/version.rb +4 -5
  49. data/redd.gemspec +30 -31
  50. data/spec/redd/objects/base_spec.rb +1 -0
  51. data/spec/redd/rate_limit_spec.rb +29 -29
  52. data/spec/redd/response/parse_json_spec.rb +12 -0
  53. data/spec/redd/response/raise_error_spec.rb +11 -0
  54. data/spec/redd_spec.rb +7 -5
  55. data/spec/spec_helper.rb +69 -50
  56. metadata +73 -136
  57. data/.yardopts +0 -1
  58. data/lib/redd/base.rb +0 -56
  59. data/lib/redd/client/authenticated.rb +0 -83
  60. data/lib/redd/client/authenticated/account.rb +0 -13
  61. data/lib/redd/client/authenticated/apps.rb +0 -13
  62. data/lib/redd/client/authenticated/flair.rb +0 -71
  63. data/lib/redd/client/authenticated/gold.rb +0 -13
  64. data/lib/redd/client/authenticated/links_comments.rb +0 -189
  65. data/lib/redd/client/authenticated/live.rb +0 -13
  66. data/lib/redd/client/authenticated/moderation.rb +0 -126
  67. data/lib/redd/client/authenticated/multis.rb +0 -9
  68. data/lib/redd/client/authenticated/private_messages.rb +0 -73
  69. data/lib/redd/client/authenticated/subreddits.rb +0 -172
  70. data/lib/redd/client/authenticated/users.rb +0 -9
  71. data/lib/redd/client/authenticated/wiki.rb +0 -9
  72. data/lib/redd/client/oauth2.rb +0 -71
  73. data/lib/redd/client/oauth2/authorization.rb +0 -108
  74. data/lib/redd/client/oauth2/identity.rb +0 -16
  75. data/lib/redd/client/oauth2_script.rb +0 -24
  76. data/lib/redd/client/oauth2_script/authorization.rb +0 -21
  77. data/lib/redd/client/unauthenticated.rb +0 -118
  78. data/lib/redd/client/unauthenticated/account.rb +0 -30
  79. data/lib/redd/client/unauthenticated/captcha.rb +0 -27
  80. data/lib/redd/client/unauthenticated/links_comments.rb +0 -60
  81. data/lib/redd/client/unauthenticated/listing.rb +0 -65
  82. data/lib/redd/client/unauthenticated/live.rb +0 -9
  83. data/lib/redd/client/unauthenticated/moderation.rb +0 -26
  84. data/lib/redd/client/unauthenticated/subreddits.rb +0 -49
  85. data/lib/redd/client/unauthenticated/users.rb +0 -67
  86. data/lib/redd/client/unauthenticated/utilities.rb +0 -109
  87. data/lib/redd/client/unauthenticated/wiki.rb +0 -33
  88. data/lib/redd/oauth2_access.rb +0 -70
  89. data/lib/redd/object/comment.rb +0 -74
  90. data/lib/redd/object/listing.rb +0 -29
  91. data/lib/redd/object/more_comments.rb +0 -14
  92. data/lib/redd/object/private_message.rb +0 -35
  93. data/lib/redd/object/submission.rb +0 -94
  94. data/lib/redd/object/subreddit.rb +0 -74
  95. data/lib/redd/object/user.rb +0 -34
  96. data/lib/redd/object/wiki_page.rb +0 -27
  97. data/lib/redd/thing.rb +0 -27
  98. data/lib/redd/thing/commentable.rb +0 -27
  99. data/lib/redd/thing/editable.rb +0 -16
  100. data/lib/redd/thing/hideable.rb +0 -16
  101. data/lib/redd/thing/inboxable.rb +0 -20
  102. data/lib/redd/thing/messageable.rb +0 -12
  103. data/lib/redd/thing/moderatable.rb +0 -32
  104. data/lib/redd/thing/reportable.rb +0 -12
  105. data/lib/redd/thing/saveable.rb +0 -16
  106. data/lib/redd/thing/voteable.rb +0 -22
  107. data/spec/README.md +0 -18
  108. data/spec/redd/base_spec.rb +0 -36
  109. data/spec/redd/client/authenticated/account_spec.rb +0 -5
  110. data/spec/redd/client/authenticated/apps_spec.rb +0 -2
  111. data/spec/redd/client/authenticated/flair_spec.rb +0 -26
  112. data/spec/redd/client/authenticated/gold_spec.rb +0 -2
  113. data/spec/redd/client/authenticated/links_comments_spec.rb +0 -231
  114. data/spec/redd/client/authenticated/live_spec.rb +0 -2
  115. data/spec/redd/client/unauthenticated/account_spec.rb +0 -15
  116. data/spec/redd/client/unauthenticated/captcha_spec.rb +0 -23
  117. data/spec/redd/client/unauthenticated/links_comments_spec.rb +0 -28
  118. data/spec/redd/client/unauthenticated/listing_spec.rb +0 -23
  119. data/spec/redd/client/unauthenticated/live_spec.rb +0 -2
  120. data/spec/redd/client/unauthenticated/moderation_spec.rb +0 -14
  121. data/spec/redd/client/unauthenticated/subreddits_spec.rb +0 -35
  122. data/spec/redd/client/unauthenticated/users_spec.rb +0 -34
  123. data/spec/redd/client/unauthenticated/wiki_spec.rb +0 -18
  124. data/spec/redd/oauth2_access_spec.rb +0 -83
  125. data/spec/redd/thing_spec.rb +0 -22
@@ -0,0 +1,66 @@
1
+ module Redd
2
+ module Clients
3
+ class Base
4
+ # Methods that require the "read" scope
5
+ module Read
6
+ # @param [Array<String>] fnames A list of fullnames.
7
+ # @return [Objects::Listing<Objects::Thing>] A listing of things with
8
+ # the fullname.
9
+ def from_fullname(*fnames)
10
+ names = fnames.join(",")
11
+ request_object(:get, "/api/info", id: names)
12
+ end
13
+
14
+ # @param [String] url The url of the thing.
15
+ # @return [Objects::Thing] The thing.
16
+ def from_url(url)
17
+ request_object(:get, "/api/info", url: url).first
18
+ end
19
+
20
+ # @param [String] name The username.
21
+ # @return [Objects::User] The user.
22
+ def user_from_name(name)
23
+ request_object(:get, "/user/#{name}/about.json")
24
+ end
25
+
26
+ # @param [String] name The subreddit's display name.
27
+ # @return [Objects::Subreddit] The subreddit if found.
28
+ def subreddit_from_name(name)
29
+ request_object(:get, "/r/#{name}/about.json")
30
+ end
31
+
32
+ # @!method get_hot(subreddit = nil, **params)
33
+ # @!method get_new(subreddit = nil, **params)
34
+ # @!method get_top(subreddit = nil, **params)
35
+ # @!method get_controversial(subreddit = nil, **params)
36
+ # @!method get_comments(subreddit = nil, **params)
37
+ #
38
+ # Get the appropriate listing.
39
+ # @param subreddit [Objects::Subreddit, String] The subreddit to query.
40
+ # @param params [Hash] A list of params to send with the request.
41
+ # @option params [String] :after Return results after the given
42
+ # fullname.
43
+ # @option params [String :before Return results before the given
44
+ # fullname.
45
+ # @option params [Integer] :count (0) The number of items already seen
46
+ # in the listing.
47
+ # @option params [1..100] :limit (25) The maximum number of things to
48
+ # return.
49
+ # @option params [:hour, :day, :week, :month, :year, :all] :t The
50
+ # time period to consider when sorting.
51
+ #
52
+ # @note The option :t only applies to the top and controversial sorts.
53
+ # @return [Objects::Listing<Objects::Thing>]
54
+ # @todo Move all listing methods into a helper?
55
+ %w(hot new top controversial comments).each do |sort|
56
+ define_method :"get_#{sort}" do |subreddit = nil, **params|
57
+ srname = property(subreddit, :display_name) if subreddit
58
+ path = "/#{sort}.json"
59
+ path = path.prepend("/r/#{srname}") if subreddit
60
+ request_object(:get, path, params)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,74 @@
1
+ require "set"
2
+
3
+ module Redd
4
+ module Clients
5
+ class Base
6
+ # Methods that stream delicious content into your bot's lazy mouth.
7
+ module Stream
8
+ # A class similar to PRAW's implementation of a BoundedSet.
9
+ class PRAWBoundedQueueSet < Set
10
+ def initialize(max, *args, &block)
11
+ @max = max
12
+ @queue = []
13
+ super(*args, &block)
14
+ end
15
+
16
+ # Add an element to the front if it isn't already in the queue.
17
+ # @param element
18
+ # @return [PRAWBoundedQueueSet] self
19
+ def enqueue(element)
20
+ @queue.push(element) if add?(element)
21
+ dequeue! if size > @max
22
+ self
23
+ end
24
+ alias_method :enq, :enqueue
25
+
26
+ # Add an element to the front if it isn't already in the queue.
27
+ # @param element
28
+ # @return [Boolean] Whether the element was added to the queue.
29
+ def enqueue?(element)
30
+ added = add?(element)
31
+ if added
32
+ @queue.push(element)
33
+ dequeue if size > @max
34
+ end
35
+ added
36
+ end
37
+ alias_method :enq?, :enqueue?
38
+
39
+ # Remove the last element of the queue.
40
+ # @return The removed element.
41
+ def dequeue
42
+ element = @queue.shift
43
+ delete(element)
44
+ element
45
+ end
46
+ alias_method :deq, :dequeue
47
+ end
48
+
49
+ # Stream the results of a method call to the given block.
50
+ # @param [Symbol] meth A method that returns a listing and has a
51
+ # keyword parameter named `:before`.
52
+ # @param [Array] args The arguments supplied to the method.
53
+ # @param [Hash] kwargs The keyword arguments supplied to the method.
54
+ # @yield An element of the returned listing.
55
+ def stream(meth = :get_new, *args, **kwargs)
56
+ bset = PRAWBoundedQueueSet.new(10)
57
+ before = ""
58
+ loop do
59
+ # Get the latest comments from the subreddit. By the way, this line
60
+ # is the one where the sleeping/rate-limiting happens.
61
+ params = kwargs.merge(before: before)
62
+ listing = send(meth, *args, **params)
63
+ # Run the loop for each of the item in the listing
64
+ listing.reverse_each do |thing|
65
+ yield thing if bset.enqueue?(thing.fullname)
66
+ end
67
+ # Set the latest comment.
68
+ before = listing.first.fullname unless listing.empty?
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,54 @@
1
+ module Redd
2
+ module Clients
3
+ class Base
4
+ # Methods that require the "submit" scope
5
+ module Submit
6
+ # Submit a link or a text post to a subreddit.
7
+ #
8
+ # @param [Objects::Submission, String] subreddit The subreddit
9
+ # to submit to.
10
+ # @param [String] title The title of the submission.
11
+ # @param [String] captcha A possible captcha result to send if one
12
+ # is required.
13
+ # @param [String] identifier The identifier for the captcha if one
14
+ # is required.
15
+ # @param [String] text The text of the self-post.
16
+ # @param [String] url The URL of the link.
17
+ # @param [Boolean] resubmit Whether to post a link to a subreddit
18
+ # despite it having been posted there before (you monster).
19
+ # @param [Boolean] sendreplies Whether to send the replies to your
20
+ # inbox.
21
+ # @return [Objects::Thing] The returned result (url, id and name).
22
+ def submit(
23
+ subreddit, title, captcha = nil, identifier = nil, text: nil,
24
+ url: nil, resubmit: false, sendreplies: true
25
+ )
26
+
27
+ params = {
28
+ extension: "json", title: title,
29
+ resubmit: resubmit, sendreplies: sendreplies,
30
+ sr: property(subreddit, :display_name)
31
+ }
32
+
33
+ params << {captcha: captcha, iden: identifier} if captcha
34
+ params[:kind], params[:text] = :self, text if text
35
+ params[:kind], params[:url] = :link, url if url
36
+
37
+ response = post("/api/submit", params)
38
+ Objects::Thing.new(self, response.body[:json][:data])
39
+ end
40
+
41
+ # Add a comment to a link, reply to a comment or reply to a message.
42
+ # Bit of an all-purpose method, this one.
43
+ # @param thing [Objects::Submission, Objects::Comment,
44
+ # Objects::PrivateMessage] A thing to add a comment to.
45
+ # @param text [String] The text to comment.
46
+ # @return [Objects::Comment, Objects::PrivateMessage] The reply.
47
+ def add_comment(thing, text)
48
+ response = post("/api/comment", text: text, thing_id: thing.fullname)
49
+ object_from_body(response.body[:json][:data][:things][0])
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,80 @@
1
+ require_relative "../../objects/base"
2
+ require_relative "../../objects/thing"
3
+ require_relative "../../objects/listing"
4
+ require_relative "../../objects/wiki_page"
5
+ require_relative "../../objects/more_comments"
6
+ require_relative "../../objects/comment"
7
+ require_relative "../../objects/user"
8
+ require_relative "../../objects/submission"
9
+ require_relative "../../objects/private_message"
10
+ require_relative "../../objects/subreddit"
11
+
12
+ module Redd
13
+ module Clients
14
+ class Base
15
+ # Internal methods that make life easier.
16
+ # @todo Move this out to Redd::Utils?
17
+ module Utilities
18
+ # The kind strings and the objects that should be used for them.
19
+ OBJECT_KINDS = {
20
+ "Listing" => Objects::Listing,
21
+ "wikipage" => Objects::WikiPage,
22
+ "more" => Objects::MoreComments,
23
+ "t1" => Objects::Comment,
24
+ "t2" => Objects::User,
25
+ "t3" => Objects::Submission,
26
+ "t4" => Objects::PrivateMessage,
27
+ "t5" => Objects::Subreddit
28
+ }
29
+
30
+ # Request and create an object from the response.
31
+ # @param [Symbol] meth The method to use.
32
+ # @param [String] path The path to visit.
33
+ # @param [Hash] params The data to send with the request.
34
+ # @return [Objects::Base] The object returned from the request.
35
+ def request_object(meth, path, params = {})
36
+ body = send(meth, path, params).body
37
+ object_from_body(body)
38
+ end
39
+
40
+ # Create an object instance with the correct attributes when given a
41
+ # body.
42
+ #
43
+ # @param [Hash] body A JSON hash.
44
+ # @return [Objects::Thing, Objects::Listing]
45
+ def object_from_body(body)
46
+ return body unless body.is_a?(Hash) || body.key?(:kind)
47
+ object = object_from_kind(body[:kind])
48
+ flat = flatten_body(body)
49
+ object.new(self, flat)
50
+ end
51
+
52
+ private
53
+
54
+ # Get a given property of a given object.
55
+ # @param [Objects::Base, String] object The object with the property.
56
+ # @param [Symbol] property The property to get.
57
+ def property(object, property)
58
+ object.respond_to?(property) ? object.send(property) : object.to_s
59
+ end
60
+
61
+ # Take a multilevel body ({kind: "tx", data: {...}}) and flatten it
62
+ # into something like {kind: "tx", ...}
63
+ # @param [Hash] body The response body.
64
+ # @return [Hash] The flattened hash.
65
+ def flatten_body(body)
66
+ data = body[:data]
67
+ data[:kind] = body[:kind]
68
+ data
69
+ end
70
+
71
+ # @param [String] kind A kind in the format /t[1-5]/.
72
+ # @return [Objects::Base, Objects::Listing] The appropriate object for
73
+ # a given kind.
74
+ def object_from_kind(kind)
75
+ OBJECT_KINDS.fetch(kind, Objects::Base)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,33 @@
1
+ module Redd
2
+ module Clients
3
+ class Base
4
+ # Methods that require the "wikiread" scope.
5
+ # @note This method is not limited to {Objects::Subreddit} because there
6
+ # are also top-level wiki pages.
7
+ module Wikiread
8
+ # Get a list of pages in the subreddit wiki.
9
+ # @param subreddit [Objects::Subreddit, String] The subreddit to
10
+ # look in.
11
+ # @return [Array<String>] An array of wikipage titles.
12
+ def get_wikipages(subreddit = nil)
13
+ path = "/wiki/pages.json"
14
+ name = property(subreddit, :display_name)
15
+ path.prepend("/r/#{name}") if subreddit
16
+ get(path).body[:data]
17
+ end
18
+
19
+ # Get a wiki page.
20
+ # @param page [String] The title of the wiki page.
21
+ # @param subreddit [Objects::Subreddit, String] The subreddit to
22
+ # look in.
23
+ # @return [Objects::WikiPage] A wiki page.
24
+ def wikipage(page, subreddit = nil)
25
+ path = "/wiki/#{page}.json"
26
+ name = property(subreddit, :display_name)
27
+ path.prepend("/r/#{name}") if subreddit
28
+ request_object(:get, path)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ require "cgi"
2
+ require_relative "base"
3
+
4
+ module Redd
5
+ module Clients
6
+ # The client for installed apps that can't keep a secret.
7
+ # It might even work with Rubymotion (fingers crossed).
8
+ class Installed < Base
9
+ # @!attribute [r] client_id
10
+ attr_reader :client_id
11
+
12
+ # @!attribute [r] redirect_uri
13
+ attr_reader :redirect_uri
14
+
15
+ # @param [Hash] options The options to create the client with.
16
+ # @see Redd.it
17
+ def initialize(client_id, redirect_uri, **options)
18
+ @client_id = client_id
19
+ @redirect_uri = redirect_uri
20
+ super(**options)
21
+ end
22
+
23
+ # @param [String] state A random string to double-check later.
24
+ # @param [Array<String>] scope The scope to request access to.
25
+ # @param [:temporary, :permanent] duration
26
+ # @return [String] The url to redirect the user to.
27
+ def auth_url(state, scope = ["identity"], duration = :temporary)
28
+ query = {
29
+ response_type: "token",
30
+ client_id: @client_id,
31
+ redirect_uri: @redirect_uri,
32
+ state: state,
33
+ scope: scope.join(","),
34
+ duration: duration
35
+ }
36
+
37
+ url = URI.join(auth_endpoint, "/api/v1/authorize")
38
+ url.query = URI.encode_www_form(query)
39
+ url.to_s
40
+ end
41
+
42
+ # Authorize using the url fragment.
43
+ # @param [String] fragment The part of the url after the "#".
44
+ # @return [Access] The access given by reddit.
45
+ def authorize!(fragment)
46
+ parsed = CGI.parse(fragment)
47
+ @access = Access.new(
48
+ access_token: parsed[:access_token].first,
49
+ expires_in: parsed[:expires_in].first,
50
+ scope: parsed[:scope]
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,37 @@
1
+ require_relative "base"
2
+
3
+ module Redd
4
+ module Clients
5
+ # The client for an account you own (e.g. bots).
6
+ class Script < Base
7
+ # @!attribute [r] client_id
8
+ attr_reader :client_id
9
+
10
+ # @!attribute [r] username
11
+ attr_reader :username
12
+
13
+ # @param [Hash] options The options to create the client with.
14
+ # @see Redd.it
15
+ def initialize(client_id, secret, username, password, **options)
16
+ @client_id = client_id
17
+ @secret = secret
18
+ @username = username
19
+ @password = password
20
+ super(**options)
21
+ end
22
+
23
+ # Authorize using the given data.
24
+ # @return [Access] The access given by reddit.
25
+ def authorize!
26
+ response = auth_connection.post(
27
+ "/api/v1/access_token",
28
+ grant_type: "password",
29
+ username: @username,
30
+ password: @password
31
+ )
32
+
33
+ @access = Access.new(response.body)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "base"
2
+
3
+ module Redd
4
+ module Clients
5
+ # The client that doesn't need a user to function.
6
+ # @note Of course, that means many editing methods throw an error.
7
+ class Userless < Base
8
+ # @!attribute [r] client_id
9
+ attr_reader :client_id
10
+
11
+ # @param [Hash] options The options to create the client with.
12
+ # @see Redd.it
13
+ def initialize(client_id, secret, **options)
14
+ @client_id = client_id
15
+ @secret = secret
16
+ super(**options)
17
+ end
18
+
19
+ # Authorize using the given data.
20
+ # @return [Access] The access given by reddit.
21
+ def authorize!
22
+ response = auth_connection.post(
23
+ "/api/v1/access_token",
24
+ grant_type: "client_credentials"
25
+ )
26
+
27
+ @access = Access.new(response.body)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ require "uri"
2
+ require_relative "base"
3
+
4
+ module Redd
5
+ module Clients
6
+ # The client for a web-based flow (e.g. "login with reddit")
7
+ class Web < Base
8
+ # @!attribute [r] client_id
9
+ attr_reader :client_id
10
+
11
+ # @!attribute [r] redirect_uri
12
+ attr_reader :redirect_uri
13
+
14
+ # @param [Hash] options The options to create the client with.
15
+ # @see Redd.it
16
+ def initialize(client_id, secret, redirect_uri, **options)
17
+ @client_id = client_id
18
+ @secret = secret
19
+ @redirect_uri = redirect_uri
20
+ super(**options)
21
+ end
22
+
23
+ # @param [String] state A random string to double-check later.
24
+ # @param [Array<String>] scope The scope to request access to.
25
+ # @param [:temporary, :permanent] duration
26
+ # @return [String] The url to redirect the user to.
27
+ def auth_url(state, scope = ["identity"], duration = :temporary)
28
+ query = {
29
+ response_type: "code",
30
+ client_id: @client_id,
31
+ redirect_uri: @redirect_uri,
32
+ state: state,
33
+ scope: scope.join(","),
34
+ duration: duration
35
+ }
36
+
37
+ url = URI.join(auth_endpoint, "/api/v1/authorize")
38
+ url.query = URI.encode_www_form(query)
39
+ url.to_s
40
+ end
41
+
42
+ # Authorize using the code given.
43
+ # @param [String] code The code from the get params.
44
+ # @return [Access] The access given by reddit.
45
+ def authorize!(code)
46
+ response = auth_connection.post(
47
+ "/api/v1/access_token",
48
+ grant_type: "authorization_code",
49
+ code: code,
50
+ redirect_uri: @redirect_uri
51
+ )
52
+
53
+ @access = Access.new(response.body)
54
+ end
55
+ end
56
+ end
57
+ end