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
@@ -1,9 +0,0 @@
1
- module Redd
2
- module Client
3
- class Authenticated
4
- # Methods to interact with multis (groups of subreddits).
5
- module Multis
6
- end
7
- end
8
- end
9
- end
@@ -1,73 +0,0 @@
1
- module Redd
2
- module Client
3
- class Authenticated
4
- # Methods for sending and reading private messages
5
- module PrivateMessages
6
- # Block the sender of the message from sending any more.
7
- #
8
- # @param message [Redd::Object::PrivateMessage, String] The message
9
- # whose sender to block.
10
- def block_message(message)
11
- fullname = extract_fullname(message)
12
- post "/api/block", id: fullname
13
- end
14
-
15
- # Compose a message to a person or the moderators of a subreddit.
16
- #
17
- # @param to [Redd::Object::User, Redd::Object::Subreddit, String] The
18
- # thing to send a message to.
19
- # @param subject [String] The subject of the message.
20
- # @param text [String] The message text.
21
- # @param captcha [String] A possible captcha result to send if one
22
- # is required.
23
- # @param identifier [String] The identifier for the captcha if one
24
- # is required.
25
- def compose_message(to, subject, text, captcha = nil, identifier = nil)
26
- params = {api_type: "json", subject: subject, text: text}
27
- params << {captcha: captcha, iden: identifier} if captcha
28
- params[:to] = extract_attribute(to, :name) ||
29
- extract_attribute(to, :display_name)
30
-
31
- post "/api/compose", params
32
- end
33
-
34
- # Mark a message as read.
35
- #
36
- # @param message [Redd::Object::PrivateMessage, String] The message
37
- # to mark as read.
38
- def mark_as_read(message)
39
- fullname = extract_fullname(message)
40
- post "/api/read_message", id: fullname
41
- end
42
-
43
- # Mark a message as unread.
44
- #
45
- # @param message [Redd::Object::PrivateMessage, String] The message
46
- # to mark as unread.
47
- def mark_as_unread(message)
48
- fullname = extract_fullname(message)
49
- post "/api/unread_message", id: fullname
50
- end
51
-
52
- # Return a list of a user's private messages.
53
- #
54
- # @param category [String] The category of messages to view.
55
- # @param mark [Boolean] Whether to remove the orangered from the
56
- # user's inbox.
57
- # @param params [Hash] A list of params to send with the request.
58
- # @option params [String] :after Return results after the given
59
- # fullname.
60
- # @option params [String] :before Return results before the given
61
- # fullname.
62
- # @option params [Integer] :count (0) The number of items already seen
63
- # in the listing.
64
- # @option params [1..100] :limit (25) The maximum number of things to
65
- # return.
66
- def messages(category = "inbox", mark = false, params = {})
67
- params[:mark] = mark
68
- object_from_response :get, "/message/#{category}.json", params
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,172 +0,0 @@
1
- module Redd
2
- module Client
3
- class Authenticated
4
- # Methods to interact with subreddits
5
- module Subreddits
6
- # Subscribe to a subreddit.
7
- #
8
- # @param subreddit [Redd::Object::Subreddit, String] The subreddit to
9
- # subscribe to.
10
- def subscribe(subreddit)
11
- edit_subscription(:sub, subreddit)
12
- end
13
-
14
- # Unsubscribe from a subreddit.
15
- #
16
- # @param subreddit [Redd::Object::Subreddit, String] The subreddit to
17
- # unsubscribe from.
18
- def unsubscribe(subreddit)
19
- edit_subscription(:unsub, subreddit)
20
- end
21
-
22
- # Get a listing of subreddits.
23
- #
24
- # @param where [:popular, :new, :subscriber, :contributor, :moderator]
25
- # The order of subreddits to return.
26
- # @param params [Hash] A list of params to send with the request.
27
- # @option params [String] :after Return results after the given
28
- # fullname.
29
- # @option params [String] :before Return results before the given
30
- # fullname.
31
- # @option params [Integer] :count (0) The number of items already seen
32
- # in the listing.
33
- # @option params [1..100] :limit (25) The maximum number of things to
34
- # return.
35
- # @return [Redd::Object::Listing] A listing of subreddits.
36
- def get_subreddits(where = :subscriber, params = {})
37
- path =
38
- if [:popular, :new].include?(where)
39
- "/subreddits/#{where}.json"
40
- elsif [:subscriber, :contributor, :moderator].include?(where)
41
- "/subreddits/mine/#{where}.json"
42
- end
43
- object_from_response(:get, path, params)
44
- end
45
-
46
- # Get users related to the subreddit.
47
- #
48
- # @param where [:banned, :wikibanned, :contributors, :wikicontributors,
49
- # :moderators] The order of users to return.
50
- # @param subreddit [Redd::Object::Subreddit, String] The subreddit.
51
- # The order of subreddits to return.
52
- # @param params [Hash] A list of params to send with the request.
53
- # @option params [String] :after Return results after the given
54
- # fullname.
55
- # @option params [String] :before Return results before the given
56
- # fullname.
57
- # @option params [Integer] :count (0) The number of items already seen
58
- # in the listing.
59
- # @option params [1..100] :limit (25) The maximum number of things to
60
- # return.
61
- # @return [Redd::Object::Listing] A listing of users.
62
- # @note On reddit's end, this is actually a UserList, which is slightly
63
- # different to a real listing, since it only provides names and ids.
64
- def get_special_users(where, subreddit, params = {})
65
- name = extract_attribute(subreddit, :display_name)
66
- response = get "/r/#{name}/about/#{where}.json", params
67
-
68
- things = response[:data][:children].map! do |user|
69
- object_from_body(kind: "t2", data: user)
70
- end
71
- Redd::Object::Listing.new(data: {children: things})
72
- end
73
-
74
- # Edit Subreddit's stylesheet
75
- #
76
- # @param subreddit [Redd::Object::Subreddit, String] The subreddit to
77
- # submit.
78
- # @param contents [String] css
79
- # @param reason [String]
80
- # @note https://www.reddit.com/r/***/about/stylesheet/ is good place
81
- # to test if you have an error
82
- def edit_stylesheet(subreddit, contents, reason = nil)
83
- name = extract_attribute(subreddit, :display_name)
84
- path = "/r/#{name}/api/subreddit_stylesheet"
85
- params = {
86
- api_type: "json",
87
- op: "save",
88
- stylesheet_contents: contents
89
- }
90
- params[:reason] = reason if reason
91
- post path, params
92
- end
93
-
94
- # Edit Subreddit's settings
95
- #
96
- # @param attrs [Hash] Settings for subrredit
97
- # @note these links might useful: https://www.reddit.com/dev/api and
98
- # https://github.com/alaycock/MeetCal-bot/blob/master/serverInfo.conf
99
- def site_admin(attrs)
100
- path = "/api/site_admin"
101
- params = {
102
- allow_top: nil, # boolean
103
- api_type: "json", # always "json"
104
- collapse_deleted_comments: nil, # boolean
105
- comment_score_hide_mins: nil, # int 0..1440 def: 0
106
- css_on_cname: nil, # boolean
107
- description: nil, # markdown string
108
- exclude_banned_modqueue: nil, # boolean
109
- lang: nil, # valid IETF lang tag, eg: en
110
- link_type: nil, # string [any, link, self]
111
- name: nil, # string subreddit name
112
- over_18: nil, # boolean
113
- public_description: nil, # markdown string
114
- public_traffic: nil, # boolean
115
- show_cname_sidebar: nil, # boolean
116
- show_media: nil, # boolean
117
- spam_comments: nil, # string [low, high, all]
118
- spam_links: nil, # string [low, high, all]
119
- spam_selfposts: nil, # string [low, high, all]
120
- sr: nil, # string, for subreddit it should start like "t5_"
121
- submit_link_label: nil, # string max 60 chars
122
- submit_text: nil, # markdown string
123
- submit_text_label: nil, # string max 60 chars
124
- title: nil, # string max 100 chars
125
- type: nil, # string [public, private, restricted, gold_restricted, archived]
126
- wiki_edit_age: nil, # int 0+, def: 0
127
- wiki_edit_karma: nil, # int 0+, def: 0
128
- wikimode: nil # string [disabled, modonly, anyone]
129
- }
130
- params["header-title"] = '' # string max 500 chars
131
-
132
- params.keys.each{|key|
133
- if !attrs[key].nil?
134
- params[key] = attrs[key]
135
- end
136
- }
137
-
138
- empties = params.map{ |obj|
139
- obj.last.nil? ? obj.first.to_s : nil
140
- }
141
- empties = empties.reject!{ |elm| elm.nil? }
142
- if !empties.empty?
143
- raise "The following item should not be nil => [" + empties.join(', ') + ']'
144
- end
145
-
146
- post path, params
147
- end
148
-
149
- # Get the current settings of a subreddit.
150
- #
151
- # @param subreddit [Redd::Object::Subreddit, String] The subreddit to
152
- # submit.
153
- def about_edit(subreddit)
154
- name = extract_attribute(subreddit, :display_name)
155
- object_from_response :get, "/r/#{name}/about/edit.json"
156
- end
157
-
158
- private
159
-
160
- # Subscribe or unsubscribe to a subreddit.
161
- #
162
- # @param action [:sub, :unsub] The type of action to perform.
163
- # @param subreddit [Redd::Object::Subreddit, String] The subreddit to
164
- # perform the action on.
165
- def edit_subscription(action, subreddit)
166
- fullname = extract_fullname(subreddit)
167
- post "/api/subscribe", action: action, sr: fullname
168
- end
169
- end
170
- end
171
- end
172
- end
@@ -1,9 +0,0 @@
1
- module Redd
2
- module Client
3
- class Authenticated
4
- # Methods to interact with other users
5
- module Users
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Redd
2
- module Client
3
- class Authenticated
4
- # Methods to interact with wiki pages
5
- module Wiki
6
- end
7
- end
8
- end
9
- end
@@ -1,71 +0,0 @@
1
- require "redd/client/authenticated"
2
-
3
- module Redd
4
- module Client
5
- # The client to connect using OAuth2.
6
- class OAuth2 < Redd::Client::Authenticated
7
- require "redd/client/oauth2/authorization"
8
- require "redd/client/oauth2/identity"
9
-
10
- include Redd::Client::OAuth2::Authorization
11
- include Redd::Client::OAuth2::Identity
12
-
13
- # @!attribute [r] auth_endpoint
14
- # @return [String] The site to connect to authenticate with.
15
- attr_accessor :auth_endpoint
16
-
17
- # @!attribute [r] client_id
18
- # @return [String] The client_id of the oauth application.
19
- attr_reader :client_id
20
-
21
- # @!attribute [r] redirect_uri
22
- # @return [String] The exact redirect_uri of the oauth application.
23
- attr_reader :redirect_uri
24
-
25
- # @!attribute [rw] access
26
- # @return [String] The access info used to make requests.
27
- attr_accessor :access
28
-
29
- def initialize(client_id, secret, redirect_uri, options = {})
30
- @client_id = client_id
31
- @secret = secret
32
- @redirect_uri = redirect_uri
33
-
34
- @rate_limit = options[:rate_limit] || Redd::RateLimit.new(1)
35
- @api_endpoint = options[:api_endpoint] || "https://oauth.reddit.com/"
36
- @auth_endpoint = options[:auth_endpoint] || "https://ssl.reddit.com/"
37
- end
38
-
39
- def with_access(access)
40
- new_instance = dup
41
- new_instance.access = access
42
- yield new_instance
43
- end
44
-
45
- private
46
-
47
- def connection
48
- @connection ||= Faraday.new(url: api_endpoint) do |faraday|
49
- faraday.use Faraday::Request::UrlEncoded
50
- faraday.use Redd::Response::RaiseError
51
- faraday.use Redd::Response::ParseJson
52
- faraday.adapter Faraday.default_adapter
53
-
54
- faraday.headers["Authorization"] = "bearer #{@access.access_token}"
55
- faraday.headers["User-Agent"] = "Redd/Ruby, v#{Redd::VERSION}"
56
- end
57
- end
58
-
59
- def auth_connection
60
- @auth_connection ||= Faraday.new(url: auth_endpoint) do |faraday|
61
- faraday.use Faraday::Request::UrlEncoded
62
- faraday.use Redd::Response::RaiseError
63
- faraday.use Redd::Response::ParseJson
64
- faraday.adapter Faraday.default_adapter
65
-
66
- faraday.basic_auth(@client_id, @secret)
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,108 +0,0 @@
1
- require "redd/oauth2_access"
2
-
3
- module Redd
4
- module Client
5
- class OAuth2
6
- # Methods for obtaining an access token
7
- module Authorization
8
- # Build an authorization url to redirect the user to.
9
- #
10
- # @param scopes [Array<String>] The access scopes to request from the
11
- # user.
12
- # @param duration [:temporary, :permanent] The duration of your access
13
- # to the user's account.
14
- # @param state [String] A random string to check later.
15
- # @return [String] The url.
16
- #
17
- # @note The access tokens from both duration last only an hour, but you
18
- # also get a refresh token when the duration is permanent.
19
- # @note You may be tempted to let the state remain "x", but seriously,
20
- # use this; it helps prevent against CSRF attacks.
21
- def auth_url(scopes = ["identity"], duration = :temporary, state = "x")
22
- path = "https://ssl.reddit.com/api/v1/authorize"
23
- scope = scopes.is_a?(Array) ? scopes.join(",") : scopes
24
- query = {
25
- client_id: @client_id,
26
- redirect_uri: @redirect_uri,
27
- response_type: "code",
28
- state: state,
29
- scope: scope,
30
- duration: duration
31
- }
32
- string_query = query.map { |key, value| "#{key}=#{value}" }.join("&")
33
- "#{path}?#{string_query}"
34
- end
35
-
36
- # Request an access token from the code that is sent with the redirect.
37
- #
38
- # @param code [String] The code that was sent in the GET request.
39
- # @param set_access [Boolean] Whether to automatically use this token
40
- # for all future requests with this client.
41
- # @return [Redd::OAuth2Access, nil] A package of the necessary
42
- # information to access the user's information or nil if there was
43
- # an error.
44
- # @todo Custom Errors for OAuth2
45
- def request_access(code, set_access = true)
46
- response = auth_connection.post "/api/v1/access_token",
47
- grant_type: "authorization_code",
48
- code: code,
49
- redirect_uri: @redirect_uri
50
-
51
- access = Redd::OAuth2Access.new(response.body)
52
- @access = access if set_access
53
- access
54
- end
55
-
56
- # Obtain a new access token using a refresh token.
57
- #
58
- # @param token [Redd::OAuth2Access, String, nil] The refresh token or
59
- # OAuth2Access. If none is provided, it'll refresh the one the client
60
- # is currently using.
61
- # @param set_access [Boolean] Whether to automatically use this token
62
- # for all future requests with this client.
63
- # @return [Redd::OAuth2Access] The refreshed information.
64
- def refresh_access(token = nil, set_access = true)
65
- refresh_token = extract_attribute(token, :refresh_token)
66
- response = auth_connection.post "/api/v1/access_token",
67
- grant_type: "refresh_token",
68
- refresh_token: refresh_token
69
-
70
- case token
71
- when nil
72
- access.refresh(response.body)
73
- when Redd::OAuth2Access
74
- token.refresh(response.body)
75
- when ::String
76
- new_access = Redd::OAuth2Access.new(response.body)
77
- @access = new_access if set_access
78
- new_access
79
- end
80
- end
81
-
82
- # Dispose of an access or refresh token when you're done with it.
83
- #
84
- # @param access [Redd::OAuth2Access, String] The token to revoke.
85
- # @param remove_refresh_token [Boolean] Whether you intend to revoke a
86
- # refresh token.
87
- def revoke_access(access, remove_refresh_token = nil)
88
- token =
89
- if remove_refresh_token
90
- extract_attribute(access, :refresh_token)
91
- else
92
- extract_attribute(access, :access_token)
93
- end
94
-
95
- params = {token: token}
96
-
97
- if remove_refresh_token
98
- params[:token_type_hint] = :refresh_token
99
- elsif remove_refresh_token == false
100
- params[:token_type_hint] = :access_token
101
- end
102
-
103
- auth_connection.post "/api/v1/revoke_token", params
104
- end
105
- end
106
- end
107
- end
108
- end