NeonRAW 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +5 -0
  5. data/.travis.yml +4 -0
  6. data/CHANGELOG.md +7 -0
  7. data/CONTRIBUTING.md +11 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.md +373 -0
  10. data/NeonRAW.gemspec +26 -0
  11. data/README.md +62 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/examples/crossposter.rb +78 -0
  16. data/examples/flairbot.rb +60 -0
  17. data/examples/publicmodlogger.rb +79 -0
  18. data/examples/settings.yaml +4 -0
  19. data/examples/userhistoryscraper.rb +108 -0
  20. data/examples/userhistorywiper.rb +10 -0
  21. data/lib/NeonRAW/clients/base/listing.rb +55 -0
  22. data/lib/NeonRAW/clients/base/objectbuilder.rb +173 -0
  23. data/lib/NeonRAW/clients/base/utilities.rb +46 -0
  24. data/lib/NeonRAW/clients/base.rb +109 -0
  25. data/lib/NeonRAW/clients/installed.rb +49 -0
  26. data/lib/NeonRAW/clients/script.rb +34 -0
  27. data/lib/NeonRAW/clients/web.rb +52 -0
  28. data/lib/NeonRAW/errors.rb +518 -0
  29. data/lib/NeonRAW/objects/access.rb +44 -0
  30. data/lib/NeonRAW/objects/all.rb +36 -0
  31. data/lib/NeonRAW/objects/comment.rb +128 -0
  32. data/lib/NeonRAW/objects/inboxcomment.rb +54 -0
  33. data/lib/NeonRAW/objects/listing.rb +12 -0
  34. data/lib/NeonRAW/objects/me.rb +268 -0
  35. data/lib/NeonRAW/objects/modlogaction.rb +59 -0
  36. data/lib/NeonRAW/objects/modloguser.rb +35 -0
  37. data/lib/NeonRAW/objects/morecomments.rb +33 -0
  38. data/lib/NeonRAW/objects/multireddit.rb +134 -0
  39. data/lib/NeonRAW/objects/privatemessage.rb +90 -0
  40. data/lib/NeonRAW/objects/rule.rb +41 -0
  41. data/lib/NeonRAW/objects/submission.rb +221 -0
  42. data/lib/NeonRAW/objects/subreddit/flair.rb +169 -0
  43. data/lib/NeonRAW/objects/subreddit/moderation.rb +200 -0
  44. data/lib/NeonRAW/objects/subreddit/utilities.rb +73 -0
  45. data/lib/NeonRAW/objects/subreddit/wiki.rb +31 -0
  46. data/lib/NeonRAW/objects/subreddit.rb +223 -0
  47. data/lib/NeonRAW/objects/thing/createable.rb +22 -0
  48. data/lib/NeonRAW/objects/thing/editable.rb +46 -0
  49. data/lib/NeonRAW/objects/thing/gildable.rb +29 -0
  50. data/lib/NeonRAW/objects/thing/inboxable.rb +26 -0
  51. data/lib/NeonRAW/objects/thing/moderateable.rb +98 -0
  52. data/lib/NeonRAW/objects/thing/refreshable.rb +21 -0
  53. data/lib/NeonRAW/objects/thing/repliable.rb +23 -0
  54. data/lib/NeonRAW/objects/thing/saveable.rb +26 -0
  55. data/lib/NeonRAW/objects/thing/votable.rb +69 -0
  56. data/lib/NeonRAW/objects/thing.rb +24 -0
  57. data/lib/NeonRAW/objects/trophy.rb +25 -0
  58. data/lib/NeonRAW/objects/user.rb +147 -0
  59. data/lib/NeonRAW/objects/wikipage.rb +176 -0
  60. data/lib/NeonRAW/objects/wikipagerevision.rb +45 -0
  61. data/lib/NeonRAW/version.rb +3 -0
  62. data/lib/NeonRAW.rb +43 -0
  63. metadata +161 -0
@@ -0,0 +1,60 @@
1
+ require 'yaml'
2
+ require 'NeonRAW'
3
+
4
+ # Creates and authenticates the client.
5
+ # @!method login(config)
6
+ # @param config [Hash] The data loaded from settings.yaml.
7
+ # @return [NeonRAW::Clients::Script] Returns the client.
8
+ def login(config)
9
+ reddit_exception_handling do
10
+ client = NeonRAW.script(config['username'], config['password'],
11
+ config['client_id'], config['secret'],
12
+ user_agent: 'Flairbot by /u/SirNeon')
13
+ return client
14
+ end
15
+ end
16
+
17
+ # Flairs submissions based on keywords in their title.
18
+ # @!method flair_shit(client, subreddit)
19
+ # @param client [NeonRAW::Clients::Script] The client.
20
+ # @param subreddit [String] The subreddit to scan.
21
+ def flair_shit(client, subreddit)
22
+ reddit_exception_handling do
23
+ subreddit = client.subreddit subreddit
24
+ submissions = subreddit.new limit: 100
25
+ submissions.each do |submission|
26
+ next if submission.flair?
27
+ case submission.title
28
+ when /\[meta\]/i then subreddit.set_flair submission, 'Meta',
29
+ css_class: 'meta'
30
+ when /test/i then subreddit.set_flair submission, 'Test'
31
+ end
32
+ end
33
+ break
34
+ end
35
+ end
36
+
37
+ # Handles Reddit exceptions.
38
+ # @!method reddit_exception_handling
39
+ # @param block [&block] The block to execute.
40
+ def reddit_exception_handling
41
+ include NeonRAW::Errors
42
+ loop do
43
+ begin
44
+ yield
45
+ rescue InvalidCredentials, InvalidOAuth2Credentials => error
46
+ abort(error.message)
47
+ rescue CouldntReachServer, ServiceUnavailable
48
+ sleep(5)
49
+ redo
50
+ end
51
+ end
52
+ end
53
+
54
+ def main
55
+ config = YAML.load_file('settings.yaml')
56
+ client = login(config)
57
+ flair_shit client, client.me.name
58
+ end
59
+
60
+ main
@@ -0,0 +1,79 @@
1
+ require 'yaml'
2
+ require 'NeonRAW'
3
+
4
+ # Creates and authenticates the client.
5
+ # @!method login(config)
6
+ # @param config [Hash] The data loaded from the settings.yaml file.
7
+ # @return [NeonRAW::Clients::Script] Returns the client.
8
+ def login(config)
9
+ reddit_exception_handling do
10
+ client = NeonRAW.script(config['username'], config['password'],
11
+ config['client_id'], config['secret'],
12
+ user_agent: 'Public mod logger by /u/SirNeon')
13
+ return client
14
+ end
15
+ end
16
+
17
+ # Fetches the modlog.
18
+ # @!method get_modlog(client, subreddit)
19
+ # @param client [NeonRAW::Clients::Script] The client.
20
+ # @param subreddit [String] The subreddit to fetch the modlog from.
21
+ # @return [NeonRAW::Objects::Listing] Returns the modlog actions.
22
+ def get_modlog(client, subreddit)
23
+ reddit_exception_handling do
24
+ subreddit = client.subreddit subreddit
25
+ modlog = subreddit.modlog limit: 100
26
+ return modlog.reverse
27
+ end
28
+ end
29
+
30
+ # Submits the modlog data to Reddit.
31
+ # @!method submit_actions(client, subreddit, modlog)
32
+ # @param client [NeonRAW::Clients::Script] The client.
33
+ # @param subreddit [String] The subreddit to submit the data to.
34
+ # @param modlog [NeonRAW::Objects::Listing] The modlog actions.
35
+ def submit_actions(client, subreddit, modlog)
36
+ reddit_exception_handling do
37
+ subreddit = client.subreddit subreddit
38
+ modlog.each do |entry|
39
+ title = entry.id
40
+ text = "Mod: #{entry.mod}\n\n"
41
+ text += "Action: #{entry.action}\n\n"
42
+ text += "Description: #{entry.description}\n\n" if entry.description
43
+ text += "Created: #{entry.created}\n\n"
44
+ text += "Target Author: #{entry.target_author}\n\n" if entry.target_author
45
+ if entry.target_permalink
46
+ text += "Target Permalink: #{entry.target_permalink}\n\n"
47
+ end
48
+ submission = subreddit.submit title, text: text
49
+ subreddit.set_flair submission, entry.action
50
+ end
51
+ break
52
+ end
53
+ end
54
+
55
+ # Handles Reddit exceptions.
56
+ # @!method reddit_exception_handling
57
+ # @param block [&block] The block to be executed.
58
+ def reddit_exception_handling
59
+ include NeonRAW::Errors
60
+ loop do
61
+ begin
62
+ yield
63
+ rescue InvalidCredentials, InvalidOAuth2Credentials => error
64
+ abort(error.message)
65
+ rescue CouldntReachServers, ServiceUnavailable
66
+ sleep(5)
67
+ redo
68
+ end
69
+ end
70
+ end
71
+
72
+ def main
73
+ config = YAML.load_file('settings.yaml')
74
+ client = login(config)
75
+ modlog = get_modlog(client, 'NeonRAW')
76
+ submit_actions(client, 'NeonRAW', modlog)
77
+ end
78
+
79
+ main
@@ -0,0 +1,4 @@
1
+ username: username
2
+ password: password
3
+ client_id: client_id
4
+ secret: secret
@@ -0,0 +1,108 @@
1
+ require 'yaml'
2
+ require 'NeonRAW'
3
+
4
+ # Creates and authenticates the client.
5
+ # @!method login(config)
6
+ # @param config [Hash] The data loaded from the settings.yaml file.
7
+ # @return [NeonRAW::Clients::Script] Returns the client.
8
+ def login(config)
9
+ reddit_exception_handling do
10
+ client = NeonRAW.script(config['username'], config['password'],
11
+ config['client_id'], config['secret'],
12
+ user_agent: 'User history scraper by /u/SirNeon')
13
+ return client
14
+ end
15
+ end
16
+
17
+ # Fetches the posts of the user.
18
+ # @!method get_posts(client, user, quantity)
19
+ # @param client [NeonRAW::Clients::Script] The client.
20
+ # @param user [String] The username of the user.
21
+ # @param quantity [1..1000] The number of posts to fetch.
22
+ # @return [NeonRAW::Objects::Listing] Returns the posts.
23
+ def get_posts(client, user, quantity)
24
+ reddit_exception_handling do
25
+ posts = client.user(user).overview limit: quantity
26
+ return posts
27
+ end
28
+ end
29
+
30
+ # Tallies the number of posts/karma per subreddit.
31
+ # @!method tally_data(posts)
32
+ # @param posts [NeonRAW::Objects::Listing] The posts.
33
+ # @return [Hash<Integer, Integer>] Returns the tallied data.
34
+ def tally_data(posts)
35
+ stats = {}
36
+ posts.each do |post|
37
+ subreddit = post.subreddit
38
+ stats[subreddit] = { posts: 0, karma: 0 } if stats[subreddit].nil?
39
+ stats[subreddit][:posts] += 1
40
+ stats[subreddit][:karma] += post.score
41
+ end
42
+ stats
43
+ end
44
+
45
+ # Sorts the data.
46
+ # @!method sort_data(data, by)
47
+ # @param data [Hash] The data.
48
+ # @param by [Symbol] The thing to sort by [posts, karma].
49
+ # @return [Hash<Integer, Integer>] Returns the sorted data.
50
+ def sort_data(data, by)
51
+ # Sort the data highest amount of posts/karma to least amount.
52
+ data.sort_by { |_subreddit, tallies| tallies[by] }.reverse.to_h
53
+ end
54
+
55
+ # Builds a table from the sorted data.
56
+ # @!method build_table(data)
57
+ # @param data [Hash] The data.
58
+ # @return [String] Returns the table.
59
+ def build_table(data)
60
+ text = "|subreddit|posts|karma|\n|:---|:---:|:---:|\n"
61
+ data.each do |subreddit, tallies|
62
+ text += "|#{subreddit}|#{tallies[:posts]}|#{tallies[:karma]}|\n"
63
+ end
64
+ text
65
+ end
66
+
67
+ # Submits the results to Reddit.
68
+ # @!method submit_results(client, subreddit, title, text)
69
+ # @param client [NeonRAW::Objects::Script] The client.
70
+ # @param subreddit [String] The name of the subreddit to submit to.
71
+ # @param title [String] The title of the thread.
72
+ # @param text [String] The table to be submitted.
73
+ def submit_results(client, subreddit, title, text)
74
+ reddit_exception_handling do
75
+ client.subreddit(subreddit).submit title, text: text
76
+ break
77
+ end
78
+ end
79
+
80
+ # Handles Reddit exceptions.
81
+ # @!method reddit_exception_handling
82
+ # @param block [&block] The block to be executed.
83
+ def reddit_exception_handling
84
+ include NeonRAW::Errors
85
+ loop do
86
+ begin
87
+ yield
88
+ rescue InvalidCredentials, InvalidOAuth2Credentials => error
89
+ abort(error.message)
90
+ rescue CouldntReachServer, ServiceUnavailable
91
+ sleep(5)
92
+ redo
93
+ end
94
+ end
95
+ end
96
+
97
+ def main
98
+ config = YAML.load_file('settings.yaml')
99
+ client = login(config)
100
+ user = client.me.name
101
+ posts = get_posts(client, user, 1000)
102
+ data = tally_data(posts)
103
+ sorted_data = sort_data(data, :posts)
104
+ text = build_table(sorted_data)
105
+ submit_results(client, user, "#{user}'s user history", text)
106
+ end
107
+
108
+ main
@@ -0,0 +1,10 @@
1
+ require 'yaml'
2
+ require 'NeonRAW'
3
+
4
+ config = YAML.load_file('settings.yaml')
5
+ client = NeonRAW.script(config['username'], config['password'],
6
+ config['client_id'], config['secret'],
7
+ user_agent: 'User history wiper by /u/SirNeon')
8
+
9
+ # Wiping your user history has never been so easy!
10
+ client.me.purge 'overview', months: 1
@@ -0,0 +1,55 @@
1
+ require_relative '../../objects/listing'
2
+ require_relative '../../objects/subreddit'
3
+ require_relative '../../objects/comment'
4
+ require_relative '../../objects/access'
5
+ require_relative '../../objects/privatemessage'
6
+ require_relative '../../objects/modlogaction'
7
+ require_relative '../../objects/inboxcomment'
8
+ require_relative '../../errors'
9
+ # rubocop:disable Metrics/AbcSize
10
+
11
+ module NeonRAW
12
+ module Clients
13
+ class Base
14
+ # Methods for building listings.
15
+ module Listings
16
+ OBJECT_KINDS = {
17
+ 'Listing' => Objects::Listing,
18
+ 'modaction' => Objects::ModLogAction,
19
+ 't1' => Objects::Comment,
20
+ 't3' => Objects::Submission,
21
+ 't4' => Objects::PrivateMessage,
22
+ 't5' => Objects::Subreddit
23
+ }.freeze
24
+
25
+ # Creates the listing object.
26
+ # @!method build_listing(path, params)
27
+ # @param path [String] The API path for the listing.
28
+ # @param params [Hash] The parameters for the request.
29
+ # @return [NeonRAW::Objects::Listing] Returns the Listing object.
30
+ def build_listing(path, params)
31
+ data_arr = []
32
+ until data_arr.length == params[:limit]
33
+ data = request_data(path, :get, params)
34
+ params[:after] = data[:data][:after]
35
+ params[:before] = data[:data][:before]
36
+ data[:data][:children].each do |item|
37
+ data_arr << if item[:kind] == 't1' &&
38
+ item[:data].key?(:was_comment)
39
+ Objects::InboxComment.new(self, item[:data])
40
+ else
41
+ OBJECT_KINDS[item[:kind]].new(self, item[:data])
42
+ end
43
+ break if data_arr.length == params[:limit]
44
+ end
45
+ break if params[:after].nil?
46
+ end
47
+ listing = OBJECT_KINDS['Listing'].new(params[:after], params[:before])
48
+ data_arr.each { |submission| listing << submission }
49
+ listing
50
+ end
51
+ private :build_listing
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,173 @@
1
+ require_relative '../../objects/subreddit'
2
+ require_relative '../../objects/user'
3
+ require_relative '../../objects/me'
4
+ require_relative '../../objects/multireddit'
5
+ require_relative '../../objects/wikipage'
6
+ require_relative '../../objects/all'
7
+
8
+ module NeonRAW
9
+ module Clients
10
+ class Base
11
+ # Methods for building objects.
12
+ module ObjectBuilder
13
+ SUBREDDIT_DEFAULTS = {
14
+ 'allow_top' => true,
15
+ 'collapse_deleted_comments' => false,
16
+ 'comment_score_hide_mins' => 0,
17
+ 'exclude_banned_modqueue' => false,
18
+ 'header-title' => '',
19
+ 'hide_ads' => false,
20
+ 'lang' => 'en',
21
+ 'link_type' => 'any',
22
+ 'over_18' => false,
23
+ 'public_traffic' => false,
24
+ 'show_media' => true,
25
+ 'spam_comments' => 'low',
26
+ 'spam_links' => 'high',
27
+ 'spam_selfposts' => 'high',
28
+ 'submit_text_label' => 'Submit a new text post',
29
+ 'submit_text' => '',
30
+ 'submit_link_label' => 'Submit a new link',
31
+ 'suggested_comment_sort' => 'confidence',
32
+ 'type' => 'public',
33
+ 'wiki_edit_age' => 0,
34
+ 'wiki_edit_karma' => 100,
35
+ 'wikimode' => 'disabled'
36
+ }.freeze
37
+
38
+ # Fetches a subreddit.
39
+ # @!method subreddit(name)
40
+ # @param name [String] The name of the subreddit.
41
+ # @return [NeonRAW::Objects::Subreddit/All] Returns the subreddit/all
42
+ # object.
43
+ def subreddit(name)
44
+ if name == 'all'
45
+ Objects::All.new(self)
46
+ else
47
+ data = request_data("/r/#{name}/about.json", :get)[:data]
48
+ Objects::Subreddit.new(self, data)
49
+ end
50
+ end
51
+
52
+ # Fetches a user.
53
+ # @!method user(name)
54
+ # @param name [String] The name of the user.
55
+ # @return [NeonRAW::Objects::User] Returns the user object.
56
+ def user(name)
57
+ data = request_data("/user/#{name}/about.json", :get)[:data]
58
+ Objects::User.new(self, data)
59
+ end
60
+
61
+ # Fetches yourself.
62
+ # @!method me
63
+ # @return [NeonRAW::Objects::Me] Returns the me object.
64
+ def me
65
+ data = request_data('/api/v1/me', :get)
66
+ Objects::Me.new(self, data)
67
+ end
68
+
69
+ # Fetches a multireddit.
70
+ # @!method multireddit(multireddit_path)
71
+ # @param multireddit_path [String] The path to the multireddit (e.g.
72
+ # /user/username/m/multireddit_name).
73
+ # @return [NeonRAW::Objects::MultiReddit] Returns the multireddit
74
+ # object.
75
+ def multireddit(multireddit_path)
76
+ params = { multipath: multireddit_path, expand_srs: false }
77
+ data = request_data("/api/multi/#{multireddit_path}", :get, params)
78
+ Objects::MultiReddit.new(self, data[:data])
79
+ end
80
+
81
+ # Creates a multireddit.
82
+ # @!method create_multireddit(data, multireddit_path)
83
+ # @param data [JSON] The multireddit data.
84
+ # @param multireddit_path [String] The path to the multireddit (e.g.
85
+ # /user/username/m/multireddit_name)
86
+ # @return [NeonRAW::Objects::MultiReddit] Returns the multireddit
87
+ # object.
88
+ # @see https://www.reddit.com/dev/api#POST_api_multi_{multipath}
89
+ def create_multireddit(data, multireddit_path)
90
+ params = { model: data, multipath: multireddit_path,
91
+ expand_srs: false }
92
+ data = request_data("/api/multi/#{multireddit_path}", :post, params)
93
+ Objects::MultiReddit.new(self, data[:data])
94
+ end
95
+
96
+ # Creates a subreddit.
97
+ # @!method create_subreddit(name, title, description, opts = {})
98
+ # @param name [String] The name of the subreddit.
99
+ # @param title [String] The title of the subreddit (100
100
+ # characters maximum).
101
+ # @param description [String] The sidebar text for the subreddit.
102
+ # @param opts [Hash] Optional parameters.
103
+ # @option opts allow_top [Boolean] Whether or not the subreddit can be
104
+ # displayed on /r/all.
105
+ # @option opts collapse_deleted_comments [Boolean] Whether or not to
106
+ # collapse deleted comments.
107
+ # @option opts comment_score_hide_mins [0..1440] The number of minutes
108
+ # to hide comment scores.
109
+ # @option opts exclude_banned_modqueue [Boolean] Whether or not to
110
+ # exclude sitewide banned users from modqueue.
111
+ # @option opts header-title [String] The title for the subreddit (500
112
+ # characters maximum).
113
+ # @option opts hide_ads [Boolean] Whether or not to hide ads in the
114
+ # subreddit.
115
+ # @option opts lang [String] The IETF language tags of the subreddit
116
+ # separated by underscores.
117
+ # @option opts link_type [String] The type of submissions allowed [any,
118
+ # link, self].
119
+ # @option opts over_18 [Boolean] Whether or not the subreddit is NSFW.
120
+ # @option opts public_description [String] The message that will get
121
+ # shown to people when the subreddit is private.
122
+ # @option opts public_traffic [Boolean] Whether or not the subreddit's
123
+ # traffic stats are publicly available.
124
+ # @option opts show_media [Boolean] Whether or not to show media.
125
+ # @option opts spam_comments [String] Set the spamfilter [low, high,
126
+ # all].
127
+ # @option opts spam_links [String] Set the spamfilter [low, high, all].
128
+ # @option opts spam_selfposts [String] Set the spamfilter [low, high,
129
+ # all].
130
+ # @option opts submit_text_label [String] The label for the selfpost
131
+ # button (60 characters maximum).
132
+ # @option opts submit_text [String] The text to display when making a
133
+ # selfpost.
134
+ # @option opts submit_link_label [String] The label for the link button
135
+ # (60 characters maximum).
136
+ # @option opts suggested_comment_sort [String] The suggested comment
137
+ # sort for the subreddit [confidence, top, new, controversial, old,
138
+ # random, qa].
139
+ # @option opts type [String] The subreddit type [gold_restricted,
140
+ # archived, restricted, gold_only, employees_only, private, public].
141
+ # @option opts wiki_edit_age [Integer] The minimum account age needed to
142
+ # edit the wiki.
143
+ # @option opts wiki_edit_karma [Integer] The minimum karma needed to
144
+ # edit the wiki.
145
+ # @option opts wikimode [String] The mode of the subreddit's wiki
146
+ # [disabled, modonly, anyone].
147
+ # @return [NeonRAW::Objects::Subreddit] Returns the subreddit object.
148
+ def create_subreddit(name, title, description, opts = {})
149
+ params = SUBREDDIT_DEFAULTS.dup
150
+ params.merge! opts
151
+ params['api_type'] = 'json'
152
+ params['name'] = name
153
+ params['title'] = title
154
+ params['description'] = description
155
+ request_data('/api/site_admin', :post, params)
156
+ subreddit(name)
157
+ end
158
+
159
+ # Fetches a wiki page.
160
+ # @!method wikipage(page)
161
+ # @param page [String] The name of the page.
162
+ # @return [NeonRAW::Objects::WikiPage] Returns the wiki page object.
163
+ def wikipage(page)
164
+ params = { page: page }
165
+ path = "/wiki/#{page}.json"
166
+ data = request_data(path, :get, params)
167
+ data[:data][:name] = page
168
+ Objects::WikiPage.new(self, data[:data])
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,46 @@
1
+ module NeonRAW
2
+ module Clients
3
+ class Base
4
+ # Utilities for the base client.
5
+ module Utilities
6
+ # Search for subreddits.
7
+ # @!method find_subreddits(query)
8
+ # @param query [String] The name to search for (50 characters maximum).
9
+ # @return [Array<String>] Returns the list of subreddits.
10
+ def find_subreddits(query)
11
+ params = { query: query }
12
+ data = request_data('/api/subreddits_by_topic', :get, params)
13
+ data.map { |subreddit| subreddit[:name] }
14
+ end
15
+
16
+ # Fetches subreddits.
17
+ # @!method popular(params = { limit: 25 })
18
+ # @!method new(params = { limit: 25 })
19
+ # @!method gold(params = { limit: 25 })
20
+ # @!method defaults(params = { limit: 25 })
21
+ # @param params [Hash] The parameters.
22
+ # @option params :after [String] Fullname of the next data block.
23
+ # @option params :before [String] Fullname of the previous data block.
24
+ # @option params :count [Integer] The number of items already in the
25
+ # listing.
26
+ # @option params :limit [1..1000] The number of listing items to fetch.
27
+ # @option params :show [String] Literally the string 'all'.
28
+ # @return [NeonRAW::Objects::Listing] Returns a listing of all the
29
+ # subreddits.
30
+ %w(popular new gold defaults).each do |type|
31
+ define_method :"#{type}" do |params = { limit: 25 }|
32
+ type.chop! if type == 'defaults'
33
+ build_listing("/subreddits/#{type}", params)
34
+ end
35
+ end
36
+
37
+ # Fetches a list of wiki pages from Reddit.
38
+ # @!method wikipages
39
+ # @return [Array<String>] Returns a list of wiki pages.
40
+ def wikipages
41
+ request_data('/wiki/pages.json', :get)[:data]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,109 @@
1
+ require 'typhoeus'
2
+ require 'json'
3
+ require_relative 'base/listing'
4
+ require_relative 'base/objectbuilder'
5
+ require_relative 'base/utilities'
6
+ require_relative '../errors'
7
+
8
+ module NeonRAW
9
+ module Clients
10
+ # The underlying base for the client
11
+ class Base
12
+ include Base::Listings
13
+ include Base::ObjectBuilder
14
+ include Base::Utilities
15
+ include Errors
16
+
17
+ # Creates headers for oAuth2 requests.
18
+ # @!method api_headers
19
+ # @return [Hash] Returns oAuth2 headers.
20
+ def api_headers
21
+ {
22
+ 'User-Agent' => @user_agent,
23
+ 'Authorization' => "bearer #{@access.access_token}"
24
+ }
25
+ end
26
+
27
+ # Connects to Reddit for oAuth2 requests.
28
+ # @!method api_connection(path, meth, params)
29
+ # @param path [String] The API path.
30
+ # @param meth [Symbol] The request method.
31
+ # @param params [Hash] The parameters.
32
+ # @param opts [Hash] Optional parameters for the request body.
33
+ # @return [Typhoeus::Response] Returns the response.
34
+ def api_connection(path, meth, params, opts = {})
35
+ response = Typhoeus::Request.new(
36
+ 'https://oauth.reddit.com' + path,
37
+ method: meth,
38
+ body: opts,
39
+ headers: api_headers,
40
+ params: params
41
+ ).run
42
+ error = assign_errors(response)
43
+ fail error unless error.nil?
44
+ handle_ratelimit(response.headers)
45
+ response
46
+ end
47
+
48
+ # Makes the connection used to authorize the client.
49
+ # @!method auth_connection(path, meth, params)
50
+ # @param path [String] The API path.
51
+ # @param meth [Symbol] The request method.
52
+ # @param params [Hash] The parameters.
53
+ # @return [Typhoeus::Response] Returns the response.
54
+ def auth_connection(path, meth, params)
55
+ response = Typhoeus::Request.new(
56
+ 'https://www.reddit.com' + path,
57
+ method: meth,
58
+ userpwd: "#{@client_id}:#{@secret}",
59
+ headers: { 'User-Agent' => @user_agent },
60
+ params: params
61
+ ).run
62
+ error = assign_errors(response)
63
+ fail error unless error.nil?
64
+ response
65
+ end
66
+
67
+ # Refreshes the access token.
68
+ # @!method refresh_access!
69
+ def refresh_access!
70
+ response = auth_connection(
71
+ '/api/v1/access_token', :post,
72
+ grant_type: 'refresh_token',
73
+ refresh_token: @access.refresh_token
74
+ )
75
+ data = JSON.parse(response.body, symbolize_names: true)
76
+ @access.refresh! data
77
+ end
78
+
79
+ # Requests data from Reddit.
80
+ # @!method request_data(path, meth, params = {})
81
+ # @param path [String] The API path to connect to.
82
+ # @param meth [Symbol] The request method to use.
83
+ # @param params [Hash] Parameters for the request.
84
+ # @param opts [Hash] Optional parameters for methods that send stuff
85
+ # via the request body.
86
+ # @return [Hash] Returns the parsed JSON containing the response data.
87
+ def request_data(path, meth, params = {}, opts = {})
88
+ refresh_access! if @access.expired?
89
+ response = api_connection(path, meth, params, opts)
90
+ data = JSON.parse(response.body, symbolize_names: true)
91
+ error = parse_errors(data)
92
+ fail error unless error.nil?
93
+ data
94
+ end
95
+
96
+ # Requests non-JSON data from Reddit.
97
+ # @!method request_nonjson(path, meth, params = {}, opts = {})
98
+ # @param path [String] The API path to connect to.
99
+ # @param meth [Symbol] The request method to use.
100
+ # @param params [Hash] Parameters for the request.
101
+ # @param opts [Hash] Optional parameters for methods that send stuff
102
+ # via the request body.
103
+ def request_nonjson(path, meth, params = {}, opts = {})
104
+ refresh_access! if @access.expired?
105
+ api_connection(path, meth, params, opts).body
106
+ end
107
+ end
108
+ end
109
+ end