redd 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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