NeonRAW 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/NeonRAW.gemspec +5 -4
  4. data/lib/NeonRAW/clients/base.rb +9 -7
  5. data/lib/NeonRAW/clients/base/objectbuilder.rb +8 -5
  6. data/lib/NeonRAW/clients/base/utilities.rb +36 -3
  7. data/lib/NeonRAW/clients/installed.rb +2 -0
  8. data/lib/NeonRAW/clients/script.rb +2 -0
  9. data/lib/NeonRAW/clients/web.rb +2 -0
  10. data/lib/NeonRAW/errors.rb +49 -58
  11. data/lib/NeonRAW/objects/all.rb +20 -2
  12. data/lib/NeonRAW/objects/comment.rb +19 -5
  13. data/lib/NeonRAW/objects/inboxcomment.rb +4 -1
  14. data/lib/NeonRAW/objects/me.rb +17 -28
  15. data/lib/NeonRAW/objects/modlogaction.rb +3 -0
  16. data/lib/NeonRAW/objects/modloguser.rb +3 -0
  17. data/lib/NeonRAW/objects/morecomments.rb +15 -12
  18. data/lib/NeonRAW/objects/multireddit.rb +4 -1
  19. data/lib/NeonRAW/objects/popular.rb +57 -0
  20. data/lib/NeonRAW/objects/privatemessage.rb +6 -3
  21. data/lib/NeonRAW/objects/rule.rb +3 -0
  22. data/lib/NeonRAW/objects/submission.rb +44 -5
  23. data/lib/NeonRAW/objects/subreddit.rb +9 -10
  24. data/lib/NeonRAW/objects/subreddit/flair.rb +7 -4
  25. data/lib/NeonRAW/objects/subreddit/moderation.rb +8 -8
  26. data/lib/NeonRAW/objects/subreddit/utilities.rb +44 -27
  27. data/lib/NeonRAW/objects/thing/inboxable.rb +1 -1
  28. data/lib/NeonRAW/objects/thing/moderateable.rb +7 -4
  29. data/lib/NeonRAW/objects/thing/refreshable.rb +1 -3
  30. data/lib/NeonRAW/objects/thing/votable.rb +1 -1
  31. data/lib/NeonRAW/objects/user.rb +51 -19
  32. data/lib/NeonRAW/objects/wikipage.rb +5 -2
  33. data/lib/NeonRAW/objects/wikipagerevision.rb +4 -1
  34. data/lib/NeonRAW/version.rb +1 -1
  35. metadata +25 -10
@@ -124,9 +124,12 @@ module NeonRAW
124
124
  def initialize(client, data)
125
125
  @client = client
126
126
  data.each do |key, value|
127
+ # for consistency, empty strings/arrays/hashes are set to nil
128
+ # because most of the keys returned by Reddit are nil when they
129
+ # don't have a value, besides a few
127
130
  value = nil if ['', [], {}].include?(value)
128
131
  instance_variable_set(:"@#{key}", value)
129
- next if key == :created || key == :created_utc
132
+ next if %i[created created_utc].include?(key)
130
133
  self.class.send(:attr_reader, key)
131
134
  end
132
135
  class << self
@@ -151,19 +154,15 @@ module NeonRAW
151
154
  # @!method rules
152
155
  # @return [Array<NeonRAW::Objects::Rule>] Returns a list of the rules.
153
156
  def rules
154
- data_arr = []
155
- data = @client.request_data("/r/#{display_name}/about/rules.json", :get)
156
- data[:rules].each do |rule|
157
- data_arr << Rule.new(@client, rule)
158
- end
159
- data_arr
157
+ data = @client.request_data("/r/#{display_name}/about/rules", :get)
158
+ data[:rules].map { |rule| Rule.new(@client, rule) }
160
159
  end
161
160
 
162
161
  # Fetches the subreddit's stylesheet.
163
162
  # @!method stylesheet
164
163
  # @return [Hash<Array, String, String>] Returns the stylesheet data.
165
164
  def stylesheet
166
- path = "/r/#{display_name}/about/stylesheet.json"
165
+ path = "/r/#{display_name}/about/stylesheet"
167
166
  @client.request_data(path, :get)[:data]
168
167
  end
169
168
 
@@ -186,9 +185,9 @@ module NeonRAW
186
185
  # @option params :limit [1..1000] The number of items to fetch.
187
186
  # @option params :show [String] Literally the string 'all'.
188
187
  # @return [NeonRAW::Objects::Listing] Returns the listing object.
189
- %w(hot rising top old new controversial comments).each do |type|
188
+ %w[hot rising top old new controversial comments].each do |type|
190
189
  define_method :"#{type}" do |params = { limit: 25 }|
191
- path = "/r/#{display_name}/#{type}/.json"
190
+ path = "/r/#{display_name}/#{type}"
192
191
  @client.send(:build_listing, path, params)
193
192
  end
194
193
  end
@@ -8,9 +8,9 @@ module NeonRAW
8
8
  module Flair
9
9
  # Clears flair templates.
10
10
  # @!method clear_flair_templates(flair_type)
11
- # @param flair_type [String] The type of flair [user, link].
11
+ # @param flair_type [Symbol] The type of flair [user, link].
12
12
  def clear_flair_templates(flair_type)
13
- flairs = { 'user' => 'USER_FLAIR', 'link' => 'LINK_FLAIR' }
13
+ flairs = { user: 'USER_FLAIR', link: 'LINK_FLAIR' }
14
14
  params = { api_type: 'json', flair_type: flairs[flair_type] }
15
15
  path = "/r/#{display_name}/api/clearflairtemplates"
16
16
  @client.request_data(path, :post, params)
@@ -77,11 +77,14 @@ module NeonRAW
77
77
 
78
78
  # Sets flairs for multiple users.
79
79
  # @!method set_many_flairs(flair_data)
80
- # @param flair_data [String] The flair data in CSV format. Format as such:
81
- # "User,flair text,CSS class\\nUser 2,flair text, CSS class".
80
+ # @param flair_data [String] The flair data in CSV format.
82
81
  # @note This API can take up to 100 lines before it starts ignoring
83
82
  # things. If the flair text and CSS class are both empty strings then
84
83
  # it will clear the user's flair.
84
+ # @example How to set mulitple user flairs.
85
+ # client = NeonRAW.script(...)
86
+ # flairs = "User,flair text,CSS class\nUser 2,flair text,CSS class"
87
+ # client.subreddit(...).set_many_flairs flairs
85
88
  def set_many_flairs(flair_data)
86
89
  params = { flair_csv: flair_data }
87
90
  path = "/r/#{display_name}/api/flaircsv"
@@ -32,7 +32,7 @@ module NeonRAW
32
32
  # @return [NeonRAW::Objects::Listing] Returns a listing of the modlog
33
33
  # actions.
34
34
  def modlog(params = { limit: 25 })
35
- path = "/r/#{display_name}/about/log.json"
35
+ path = "/r/#{display_name}/about/log"
36
36
  @client.send(:build_listing, path, params)
37
37
  end
38
38
 
@@ -69,10 +69,10 @@ module NeonRAW
69
69
  # @option params :show [String] Literally the string 'all'.
70
70
  # @return [NeonRAW::Objects::Listing] Returns a listing with all the
71
71
  # things.
72
- %w(reported spam modqueue unmoderated edited).each do |type|
72
+ %w[reported spam modqueue unmoderated edited].each do |type|
73
73
  define_method :"#{type}" do |params = { limit: 25 }|
74
74
  type = 'reports' if type == 'reported'
75
- path = "/r/#{display_name}/about/#{type}.json"
75
+ path = "/r/#{display_name}/about/#{type}"
76
76
  @client.send(:build_listing, path, params)
77
77
  end
78
78
  end
@@ -93,8 +93,8 @@ module NeonRAW
93
93
  # @option params :show [String] Literally the string 'all'.
94
94
  # @option params :user [String] The name of the user to fetch.
95
95
  # @return [NeonRAW::Objects::Listing] Returns a listing of the users.
96
- %w(banned muted wikibanned
97
- contributors wikicontributors moderators).each do |type|
96
+ %w[banned muted wikibanned
97
+ contributors wikicontributors moderators].each do |type|
98
98
  define_method :"#{type}" do |params = { limit: 25 }|
99
99
  data_arr = []
100
100
  path = "/r/#{display_name}/about/#{type}"
@@ -127,7 +127,7 @@ module NeonRAW
127
127
  # Ditch your privileged status in the subreddit.
128
128
  # @!method leave_contributor!
129
129
  # @!method leave_moderator!
130
- %w(contributor moderator).each do |type|
130
+ %w[contributor moderator].each do |type|
131
131
  define_method :"leave_#{type}!" do
132
132
  params = { id: name }
133
133
  @client.request_data("/api/leave#{type}", :post, params)
@@ -155,7 +155,7 @@ module NeonRAW
155
155
  # @!method remove_banner!
156
156
  # @!method remove_header!
157
157
  # @!method remove_icon!
158
- %w(banner header icon).each do |type|
158
+ %w[banner header icon].each do |type|
159
159
  define_method :"remove_#{type}!" do
160
160
  params = { api_type: 'json' }
161
161
  path = "/r/#{display_name}/api/delete_sr_#{type}"
@@ -191,7 +191,7 @@ module NeonRAW
191
191
  # @!method settings
192
192
  # @return [Hash] Returns the subreddit's settings.
193
193
  def settings
194
- path = "/r/#{display_name}/about/edit.json"
194
+ path = "/r/#{display_name}/about/edit"
195
195
  @client.request_data(path, :get)[:data]
196
196
  end
197
197
  end
@@ -3,29 +3,6 @@ module NeonRAW
3
3
  class Subreddit
4
4
  # Utilities for subreddits.
5
5
  module Utilities
6
- # Get info on a link/comment/subreddit.
7
- # @!method info(params = {})
8
- # @param params [Hash] The parameters.
9
- # @option params :name [String] The fullname of the thing.
10
- # @option params :url [String] The URL of the thing.
11
- # @return [NeonRAW::Objects::Comment/Submission/Subreddit] Returns the
12
- # object.
13
- # @see https://www.reddit.com/dev/api#fullnames
14
- def info(params = {})
15
- params[:id] = params[:name]
16
- params.delete(:name)
17
- path = "/r/#{display_name}/api/info"
18
- data = @client.request_data(path, :get, params)
19
- case data[:data][:children][0][:kind]
20
- when 't1'
21
- Comment.new(@client, data[:data][:children][0][:data])
22
- when 't3'
23
- Submission.new(@client, data[:data][:children][0][:data])
24
- when 't5'
25
- Subreddit.new(@client, data[:data][:children][0][:data])
26
- end
27
- end
28
-
29
6
  # Submit a thread to the subreddit.
30
7
  # @!method submit(title, params = {})
31
8
  # @param title [String] The title of the submission (300
@@ -34,15 +11,16 @@ module NeonRAW
34
11
  # @option params :text [String] The text of the submission (selfpost).
35
12
  # @option params :url [String] The URL of the submission (link post).
36
13
  # @return [NeonRAW::Objects::Submission] Returns the submission object.
14
+ # @note This method uses 2 API requests, as it calls #info since the
15
+ # JSON returned doesn't give you the submission data.
37
16
  def submit(title, params = {})
38
17
  params[:kind] = 'self' if params[:text]
39
18
  params[:kind] = 'link' if params[:url]
19
+ params[:api_type] = 'json'
40
20
  params[:sr] = display_name
41
21
  params[:title] = title
42
22
  response = @client.request_data('/api/submit', :post, params)
43
- # Seriously though, fucking convoluted data structures.
44
- submission_id = response[:jquery].last[3].first.split('/')[6]
45
- info(name: 't3_' + submission_id)
23
+ @client.info(name: response[:json][:data][:name]).first
46
24
  end
47
25
 
48
26
  # Gets recommended subreddits for the subreddit.
@@ -61,7 +39,7 @@ module NeonRAW
61
39
  # Toggle your subscription to the subreddit.
62
40
  # @!method subscribe!
63
41
  # @!method unsubscribe!
64
- %w(subscribe unsubscribe).each do |type|
42
+ %w[subscribe unsubscribe].each do |type|
65
43
  define_method :"#{type}!" do
66
44
  params = { sr: name }
67
45
  params[:action] = 'sub' if type == 'subscribe'
@@ -70,6 +48,45 @@ module NeonRAW
70
48
  refresh!
71
49
  end
72
50
  end
51
+
52
+ # Streams content from subreddits.
53
+ # @!method stream(queue, params = { limit: 25 })
54
+ # @param queue [Symbol] The queue to get data from [hot, top, new,
55
+ # controversial, gilded, comments]
56
+ # @param params [Hash] The parameters for the request.
57
+ # @option params :t [String] Time for relevant sorting [hour, day, week,
58
+ # month, year, all]
59
+ # @option params :after [String] The name of the next data block.
60
+ # @option params :before [String] The name of the previous data block.
61
+ # @option params :count [Integer] The number of items already in the
62
+ # listing.
63
+ # @option params :limit [1..1000] The number of items to fetch.
64
+ # @option params :show [String] Literally the string 'all'.
65
+ # @yield [NeonRAW::Objects::Comment/Submission] Yields listing items.
66
+ # @return [Enumerator] Returns an enumerator for the streamed data.
67
+ # @example Simple comment stream.
68
+ # client = NeonRAW.script(...)
69
+ # comments = client.subreddit(...).stream :comments
70
+ # comments.each do |comment|
71
+ # comment.reply 'world' if comment.body =~ /hello/i
72
+ # end
73
+ def stream(queue, params = { limit: 25 })
74
+ @client.send(:stream, "/r/#{display_name}/#{queue}", params)
75
+ end
76
+
77
+ # Returns data on the moderators of the subreddit.
78
+ # @!method moderators
79
+ # @return [Array<Hash<String, String, Array<String>, Float, String,
80
+ # String>>] Returns data on the moderators.
81
+ def moderators
82
+ path = "/r/#{display_name}/about/moderators"
83
+ data = @client.request_data(path, :get)[:data][:children]
84
+ data.each do |user|
85
+ user[:username] = user.delete(:name)
86
+ user[:name] = user.delete(:id) # this is for consistency
87
+ end
88
+ data
89
+ end
73
90
  end
74
91
  end
75
92
  end
@@ -6,7 +6,7 @@ module NeonRAW
6
6
  # Changes the read status of a PM.
7
7
  # @!method mark_as_read
8
8
  # @!method mark_as_unread
9
- %w(read unread).each do |type|
9
+ %w[read unread].each do |type|
10
10
  define_method :"mark_as_#{type}" do
11
11
  params = { id: name }
12
12
  @client.request_data("/api/#{type}_message", :post, params)
@@ -31,12 +31,15 @@ module NeonRAW
31
31
  end
32
32
 
33
33
  # Distinguish a submission/comment.
34
- # @!method distinguish(type)
34
+ # @!method distinguish!(type, params = { sticky: nil })
35
35
  # @param type [String] The type of distinguish you want to do [yes, no,
36
36
  # admin, special].
37
+ # @param params [Hash<Symbol>] Optional parameters.
38
+ # @option params :sticky [Boolean] Whether or not you want the post
39
+ # stickied (top level mod comments only!)
37
40
  # @!group Moderators
38
- def distinguish(type)
39
- params = { api_type: 'json', how: type, id: name }
41
+ def distinguish!(type, params = { sticky: nil })
42
+ params.merge!(api_type: 'json', how: type, id: name)
40
43
  @client.request_data('/api/distinguish', :post, params)
41
44
  refresh!
42
45
  end
@@ -69,7 +72,7 @@ module NeonRAW
69
72
  # Set whether to ignore reports on the thing or not.
70
73
  # @!method ignore_reports!
71
74
  # @!method unignore_reports!
72
- %w(ignore unignore).each do |type|
75
+ %w[ignore unignore].each do |type|
73
76
  define_method :"#{type}_reports!" do
74
77
  params = { id: name }
75
78
  @client.request_data("/api/#{type}_reports", :post, params)
@@ -7,9 +7,7 @@ module NeonRAW
7
7
  # @!method refresh!
8
8
  def refresh!
9
9
  params = { id: name }
10
- path = "/r/#{display_name}/api/info" if /t5_/ =~ name
11
- path = "/r/#{subreddit}/api/info" unless /t5_/ =~ name
12
- data = @client.request_data(path, :get, params)
10
+ data = @client.request_data('/api/info', :get, params)
13
11
  data[:data][:children][0][:data].each do |key, value|
14
12
  value = nil if ['', [], {}].include?(value)
15
13
  instance_variable_set(:"@#{key}", value)
@@ -55,7 +55,7 @@ module NeonRAW
55
55
  # @!method upvote
56
56
  # @!method clear_vote
57
57
  # @!method downvote
58
- %i(upvote clear_vote downvote).each do |type|
58
+ %i[upvote clear_vote downvote].each do |type|
59
59
  define_method type do
60
60
  params = { dir: votes[type], id: name }
61
61
  @client.request_data('/api/vote', :post, params)
@@ -17,10 +17,16 @@ module NeonRAW
17
17
  # @!attribute [r] hide_from_robots?
18
18
  # @return [Boolean] Returns whether or not the user doesn't
19
19
  # want web crawlers indexing their profile page.
20
+ # @!attribute [r] suspended?
21
+ # @return [Boolean] Returns whether or not the user is suspended.
20
22
  # @!attribute [r] link_karma
21
23
  # @return [Integer] Returns the link karma of the user.
22
24
  # @!attribute [r] comment_karma
23
25
  # @return [Integer] Returns the comment karma of the user.
26
+ # @!attribute [r] name
27
+ # @return [String] Returns the fullname of the user.
28
+ # @!attribute [r] username
29
+ # @return [String] Returns the username of the user.
24
30
  class User < Thing
25
31
  include Thing::Createable
26
32
  include Thing::Refreshable
@@ -31,10 +37,17 @@ module NeonRAW
31
37
  # @param data [Hash] The object data.
32
38
  def initialize(client, data)
33
39
  @client = client
40
+ # is_suspended only gets included when the user is actually suspended
41
+ data[:is_suspended] = false unless data.key?(:is_suspended)
42
+ data[:username] = data.delete(:name) # this is for consistency
43
+ data[:name] = 't2_' + data[:id]
34
44
  data.each do |key, value|
45
+ # for consistency, empty strings/arrays/hashes are set to nil
46
+ # because most of the keys returned by Reddit are nil when they
47
+ # don't have a value, besides a few
35
48
  value = nil if ['', [], {}].include?(value)
36
49
  instance_variable_set(:"@#{key}", value)
37
- next if key == :created || key == :created_utc
50
+ next if %i[created created_utc].include?(key)
38
51
  self.class.send(:attr_reader, key)
39
52
  end
40
53
  class << self
@@ -43,6 +56,7 @@ module NeonRAW
43
56
  alias_method :moderator?, :is_mod
44
57
  alias_method :verified_email?, :has_verified_email
45
58
  alias_method :hide_from_robots?, :hide_from_robots
59
+ alias_method :suspended?, :is_suspended
46
60
  end
47
61
  end
48
62
 
@@ -70,13 +84,38 @@ module NeonRAW
70
84
  # listing.
71
85
  # @option params :limit [1..1000] The number of listing items to fetch.
72
86
  # @return [NeonRAW::Objects::Listing] Returns the listing object.
73
- %w(overview comments submitted gilded upvoted downvoted
74
- hidden saved).each do |type|
87
+ %w[overview comments submitted gilded upvoted downvoted
88
+ hidden saved].each do |type|
75
89
  define_method :"#{type}" do |params = { limit: 25 }|
76
- path = "/user/#{name}/#{type}/.json"
90
+ path = "/user/#{username}/#{type}"
77
91
  @client.send(:build_listing, path, params)
78
92
  end
79
93
  end
94
+
95
+ # Streams content from users.
96
+ # @!method stream(queue, params = { limit: 25 })
97
+ # @param queue [Symbol] The queue to get data from [overview, comments,
98
+ # submitted, gilded, upvoted, downvoted, hidden, saved]
99
+ # @param params [Hash] The parameters for the request.
100
+ # @option params :t [String] Time for relevant sorting [hour, day, week,
101
+ # month, year, all]
102
+ # @option params :after [String] The name of the next data block.
103
+ # @option params :before [String] The name of the previous data block.
104
+ # @option params :count [Integer] The number of items already in the
105
+ # listing.
106
+ # @option params :limit [1..1000] The number of items to fetch.
107
+ # @option params :show [String] Literally the string 'all'.
108
+ # @yield [NeonRAW::Objects::Comment/Submission] Yields the listing items.
109
+ # @return [Enumerator] Returns an enumerator for the streamed data.
110
+ # @example Simple comment stream.
111
+ # client = NeonRAW.script(...)
112
+ # comments = client.subreddit(...).stream :comments
113
+ # comments.each do |comment|
114
+ # comment.reply 'world' if comment.body =~ /hello/i
115
+ # end
116
+ def stream(queue, params = { limit: 25 })
117
+ @client.send(:stream, "/user/#{username}/#{queue}", params)
118
+ end
80
119
  # @!endgroup
81
120
 
82
121
  # Give gold to a user.
@@ -84,7 +123,7 @@ module NeonRAW
84
123
  # @param months [1..36] The number of months worth of gold to give.
85
124
  def give_gold(months)
86
125
  params = { months: months }
87
- @client.request_data("/api/v1/gold/give/#{name}", :post, params)
126
+ @client.request_data("/api/v1/gold/give/#{username}", :post, params)
88
127
  refresh!
89
128
  end
90
129
 
@@ -107,40 +146,33 @@ module NeonRAW
107
146
  # @return [Array<NeonRAW::Objects::MultiReddit>] Returns a list of
108
147
  # multireddits.
109
148
  def multireddits
110
- data_arr = []
111
149
  params = { expand_srs: false }
112
- data = @client.request_data("/api/multi/user/#{name}", :get, params)
113
- data.each do |multireddit|
114
- data_arr << MultiReddit.new(@client, multireddit[:data])
115
- end
116
- data_arr
150
+ data = @client.request_data("/api/multi/user/#{username}", :get, params)
151
+ data.map { |multireddit| MultiReddit.new(@client, multireddit[:data]) }
117
152
  end
118
153
 
119
154
  # Add the user to your friends list.
120
155
  # @!method friend
121
156
  def friend
122
157
  body = { 'name' => name }.to_json
123
- @client.request_data("/api/v1/me/friends/#{name}", :put, {}, body)
158
+ @client.request_data("/api/v1/me/friends/#{username}", :put, {}, body)
124
159
  end
125
160
 
126
161
  # Remove the user from your friends list.
127
162
  # @!method unfriend
128
163
  def unfriend
129
164
  params = { id: name }
130
- @client.request_nonjson("/api/v1/me/friends/#{name}", :delete, params)
165
+ path = "/api/v1/me/friends/#{username}"
166
+ @client.request_nonjson(path, :delete, params)
131
167
  end
132
168
 
133
169
  # Fetches the user's trophies.
134
170
  # @!method trophies
135
171
  # @return [Array<NeonRAW::Objects::Trophy>] Returns a list of trophies.
136
172
  def trophies
137
- data_arr = []
138
- path = "/api/v1/user/#{name}/trophies"
173
+ path = "/api/v1/user/#{username}/trophies"
139
174
  data = @client.request_data(path, :get)[:data]
140
- data[:trophies].each do |trophy|
141
- data_arr << Trophy.new(trophy[:data])
142
- end
143
- data_arr
175
+ data[:trophies].map { |trophy| Trophy.new(trophy[:data]) }
144
176
  end
145
177
  end
146
178
  end
@@ -27,9 +27,12 @@ module NeonRAW
27
27
  def initialize(client, data)
28
28
  @client = client
29
29
  data.each do |key, value|
30
+ # for consistency, empty strings/arrays/hashes are set to nil
31
+ # because most of the keys returned by Reddit are nil when they
32
+ # don't have a value, besides a few
30
33
  value = nil if ['', [], {}].include?(value)
31
34
  instance_variable_set(:"@#{key}", value)
32
- next if key == :revision_date || key == :revision_by
35
+ next if %i[revision_date revision_by].include?(key)
33
36
  self.class.send(:attr_reader, key)
34
37
  end
35
38
  class << self
@@ -104,7 +107,7 @@ module NeonRAW
104
107
  # @!method add_editor(username)
105
108
  # @!method remove_editor(username)
106
109
  # @param username [String] The username of the user.
107
- %w(add remove).each do |type|
110
+ %w[add remove].each do |type|
108
111
  define_method :"#{type}_editor" do |username|
109
112
  params = { page: name, username: username }
110
113
  type = 'del' if type == 'remove'