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
@@ -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