NeonRAW 0.1.6 → 0.1.7

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 (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'