redd 0.1.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +38 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +5 -0
  5. data/.travis.yml +10 -0
  6. data/.yardopts +1 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +10 -0
  10. data/Rakefile +10 -0
  11. data/github/redd.png +0 -0
  12. data/lib/redd.rb +14 -0
  13. data/lib/redd/RedditKit.LICENSE.md +13 -0
  14. data/lib/redd/base.rb +35 -0
  15. data/lib/redd/client/authenticated.rb +88 -0
  16. data/lib/redd/client/authenticated/account.rb +9 -0
  17. data/lib/redd/client/authenticated/apps.rb +12 -0
  18. data/lib/redd/client/authenticated/flair.rb +9 -0
  19. data/lib/redd/client/authenticated/gold.rb +12 -0
  20. data/lib/redd/client/authenticated/links_comments.rb +9 -0
  21. data/lib/redd/client/authenticated/live.rb +12 -0
  22. data/lib/redd/client/authenticated/moderation.rb +9 -0
  23. data/lib/redd/client/authenticated/multis.rb +9 -0
  24. data/lib/redd/client/authenticated/private_messages.rb +40 -0
  25. data/lib/redd/client/authenticated/subreddits.rb +9 -0
  26. data/lib/redd/client/authenticated/users.rb +9 -0
  27. data/lib/redd/client/authenticated/wiki.rb +9 -0
  28. data/lib/redd/client/oauth2.rb +9 -0
  29. data/lib/redd/client/unauthenticated.rb +104 -0
  30. data/lib/redd/client/unauthenticated/account.rb +21 -0
  31. data/lib/redd/client/unauthenticated/links_comments.rb +15 -0
  32. data/lib/redd/client/unauthenticated/listing.rb +44 -0
  33. data/lib/redd/client/unauthenticated/subreddits.rb +13 -0
  34. data/lib/redd/client/unauthenticated/utilities.rb +61 -0
  35. data/lib/redd/client/unauthenticated/wiki.rb +9 -0
  36. data/lib/redd/error.rb +93 -0
  37. data/lib/redd/object/comment.rb +41 -0
  38. data/lib/redd/object/listing.rb +24 -0
  39. data/lib/redd/object/submission.rb +94 -0
  40. data/lib/redd/object/subreddit.rb +10 -0
  41. data/lib/redd/rate_limit.rb +48 -0
  42. data/lib/redd/response/parse_json.rb +31 -0
  43. data/lib/redd/response/raise_error.rb +20 -0
  44. data/lib/redd/thing.rb +27 -0
  45. data/lib/redd/version.rb +5 -0
  46. data/redd.gemspec +32 -0
  47. data/spec/redd_spec.rb +7 -0
  48. data/spec/spec_helper.rb +33 -0
  49. metadata +234 -0
@@ -0,0 +1,94 @@
1
+ require "redd/thing"
2
+
3
+ module Redd
4
+ module Object
5
+ # A submission made in a subreddit.
6
+ class Submission < Redd::Thing
7
+ # @!attribute [r] title
8
+ # @return [String] The title of the submission.
9
+ attr_reader :title
10
+
11
+ # @!attribute [r] url
12
+ # @return [String] The url the submission links to.
13
+ attr_reader :url
14
+
15
+ # @!attribute [r] num_comments
16
+ # @return [Integer] The number of comments the submission has.
17
+ attr_reader :num_comments
18
+
19
+ # @!attribute [r] domain
20
+ # @return [String] The domain the url belongs to.
21
+ attr_reader :domain
22
+
23
+ # @!attribute [r] subreddit
24
+ # @return [String] The name of the subreddit this comment belongs to.
25
+ # @todo Convert to a Subreddit object?
26
+ attr_reader :subreddit
27
+
28
+ # @!attribute [r] is_self?
29
+ # @return [Boolean] Whether the submission is a self submission.
30
+ attr_reader :self?, :is_self
31
+
32
+ # @!attribute [r] thumbnail
33
+ # @return [String] The url for the thumbnail of the submission.
34
+ attr_reader :thumbnail
35
+ alias_method :thumbnail_url, :thumbnail
36
+
37
+ # @!attribute [r] selftext
38
+ # @return [String] The text of the submission in markdown.
39
+ # @note This returns "" if the submission is not a self submission.
40
+ attr_reader :selftext
41
+
42
+ # @!attribute [r] selftext_html
43
+ # @return [String] The text of the submission in html.
44
+ # @note This returns nil if the submission is not a self submission.
45
+ # @note Be warned: this isn't actual html, but escaped html. So all the
46
+ # <'s and >'s are converted to &lt;'s and &gt;'s.
47
+ attr_reader :selftext_html
48
+
49
+ # @!attribute [r] link_flair_text
50
+ # @return [String] The submission's flair.
51
+ attr_reader :link_flair_text
52
+
53
+ # @!attribute [r] link_flair_css_class
54
+ # @return [String] The CSS class of the submission's flair.
55
+ attr_reader :link_flair_css_class
56
+
57
+ # @!attribute [r] author_flair_text
58
+ # @return [String] The user's flair.
59
+ attr_reader :author_flair_text
60
+
61
+ # @!attribute [r] author_flair_css_class
62
+ # @return [String] The CSS class of the user's flair.
63
+ attr_reader :author_flair_css_class
64
+
65
+ # @!attribute [r] clicked
66
+ # @return [Boolean] Whether the user already clicked on the link before.
67
+ # @note This only works for users with reddit gold.
68
+ attr_reader :clicked
69
+
70
+ # @!attribute [r] visited
71
+ # @return [Boolean] Whether the user already visited on the link before.
72
+ # @note I have no idea what the difference between this and {#clicked} is
73
+ attr_reader :visited
74
+
75
+ # @!attribute [r] stickied
76
+ # @return [Boolean] Whether the submission was stickied in the subreddit.
77
+ attr_reader :stickied
78
+
79
+ # @!attribute [r] nsfw?
80
+ # @return [Boolean] Whether the post is marked as NSFW.
81
+ attr_reader :nsfw?, :over_18
82
+
83
+ # @return [String] The full url to the post on reddit.com.
84
+ def permalink
85
+ "http://www.reddit.com" + attributes[:permalink]
86
+ end
87
+
88
+ # @return [String] The short url on redd.it.
89
+ def short_url
90
+ "http://redd.it/" + id
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,10 @@
1
+ require "redd/thing"
2
+
3
+ module Redd
4
+ module Object
5
+ # A comment made on links.
6
+ # @note This model can sure benefit from some lazy-loading...
7
+ class Subreddit < Redd::Thing
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,48 @@
1
+ module Redd
2
+ # The class that handles rate limiting for reddit. reddit does supply
3
+ # X-Ratelimit headers but only when logged in and using those headers instead
4
+ # would just lead to short bursts, so it's better to go at a constant speed
5
+ # and space out requests every 2 seconds.
6
+ #
7
+ # If you'd rather have short bursts or no rate limiting at all, it's easy to
8
+ # write one yourself. A rate limiting class is any class that has an
9
+ # {#after_limit} method. The block returns a Faraday::Response object, so you
10
+ # can also extract the headers from the response and use those instead. To
11
+ # remove rate limiting entirely, follow the example below.
12
+ #
13
+ # @example No Rate Limiting
14
+ # class IWantToGetIPBanned
15
+ # def after_limit
16
+ # yield
17
+ # end
18
+ # end
19
+ #
20
+ # client = Redd::Unauthenticated.new(rate_limit: IWantToGetIPBanned.new)
21
+ #
22
+ # @note The class itself doesn't perform the rate limiting but only acts
23
+ # as an updatable container for the values.
24
+ class RateLimit
25
+ # @!attribute [r] last_request_time
26
+ # @return [String] The time when the last request took place.
27
+ attr_reader :last_request_time
28
+
29
+ def initialize
30
+ # Some time ages ago, because we never made a request.
31
+ @last_request_time = Time.at(0)
32
+ end
33
+
34
+ # Sleep until 2 seconds have passed since the last request and perform the
35
+ # given request.
36
+ #
37
+ # @param [Float, Integer] gap The minimum time between each request.
38
+ # @yield A block.
39
+ # @return The return value of the block.
40
+ def after_limit(gap = 2)
41
+ seconds_passed = Time.now - @last_request_time
42
+ wait_time = gap - seconds_passed
43
+ sleep(wait_time) if wait_time > 0
44
+ @last_request_time = Time.now
45
+ yield
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module Redd
2
+ # The module that contains middleware that alters the Faraday response.
3
+ module Response
4
+ # Faraday Middleware that parses JSON using Oj.
5
+ class ParseJson < Faraday::Middleware
6
+ dependency do
7
+ require "oj" unless defined?(::Oj)
8
+ end
9
+
10
+ # Call the middleware.
11
+ # @param faraday
12
+ def call(faraday)
13
+ @app.call(faraday).on_complete do |env|
14
+ env[:body] = parse(env[:body])
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ # Parse a JSON string and return a symbolized hash.
21
+ #
22
+ # @param [String] body The JSON string to parse.
23
+ # @return [Hash] A symbolized parsed JSON hash.
24
+ def parse(body)
25
+ Oj.load(body, symbol_keys: true)
26
+ rescue Oj::ParseError
27
+ body
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ require "redd/error"
2
+
3
+ module Redd
4
+ module Response
5
+ # Raises the appropriate error when one comes up.
6
+ class RaiseError < Faraday::Middleware
7
+ # Call the middleware.
8
+ # @param faraday
9
+ def call(faraday)
10
+ @app.call(faraday).on_complete do |env|
11
+ error = Redd::Error.from_response(env)
12
+ if error
13
+ info = Redd::Error.parse_error(env[:body])
14
+ fail error, info
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/redd/thing.rb ADDED
@@ -0,0 +1,27 @@
1
+ require "redd/base"
2
+
3
+ module Redd
4
+ # A reddit thing.
5
+ # @see http://www.reddit.com/dev/api#fullnames
6
+ class Thing < Redd::Base
7
+ # @!attribute [r] id
8
+ # @return [String] The id value for the thing.
9
+ attr_reader :id
10
+
11
+ # @!attribute [r] kind
12
+ # @return [String] The kind of the thing.
13
+ attr_reader :kind
14
+
15
+ # Check for equality.
16
+ # @param other The other object.
17
+ # @return [Boolean]
18
+ def ==(other)
19
+ other.is_a?(Redd::Thing) && full_name == other.full_name
20
+ end
21
+
22
+ # @return [String] The fullname of the thing.
23
+ def fullname
24
+ @fullname ||= (attributes[:name] || "#{kind}_#{id}")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ # The main Redd module.
2
+ module Redd
3
+ # The semantic version number for Redd.
4
+ VERSION = "0.1.0"
5
+ end
data/redd.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "redd/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "redd"
8
+ s.version = Redd::VERSION
9
+ s.authors = ["Avinash Dwarapu"]
10
+ s.email = ["d.nash.avi@gmail.com"]
11
+ s.summary = "A Reddit API Wrapper for Ruby."
12
+ s.description = "A Reddit API Wrapper for Ruby."
13
+ s.homepage = ""
14
+ s.license = "MIT"
15
+
16
+ s.files = `git ls-files -z`.split("\x0")
17
+ s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
18
+ s.test_files = s.files.grep(/^(test|spec|features)\//)
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "bundler", "~> 1.6"
22
+ s.add_development_dependency "rubocop"
23
+ s.add_development_dependency "rake"
24
+ s.add_development_dependency "yard"
25
+ s.add_development_dependency "rspec"
26
+ s.add_development_dependency "vcr"
27
+ s.add_development_dependency "webmock"
28
+
29
+ s.add_dependency "faraday", "~> 0.9.0"
30
+ s.add_dependency "memoizable"
31
+ s.add_dependency "oj"
32
+ end
data/spec/redd_spec.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe Redd do
4
+ it "has a semantic version number" do
5
+ expect(Redd::VERSION).to match(/\d\.\d\.\d/)
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ require "rspec"
2
+ require "webmock"
3
+ require "vcr"
4
+
5
+ require "redd"
6
+
7
+ VCR.configure do |config|
8
+ config.cassette_library_dir = "spec/cassettes"
9
+ config.hook_into :webmock
10
+ end
11
+
12
+ RSpec.configure do |config|
13
+ config.filter_run :focus
14
+ config.run_all_when_everything_filtered = true
15
+ config.profile_examples = 10
16
+ config.order = :random
17
+ Kernel.srand config.seed
18
+
19
+ config.expect_with :rspec do |expectations|
20
+ expectations.syntax = :expect
21
+ end
22
+
23
+ config.mock_with :rspec do |mocks|
24
+ mocks.syntax = :expect
25
+ mocks.verify_partial_doubles = true
26
+ end
27
+
28
+ config.around :each do |example|
29
+ VCR.use_cassette example.metadata[:full_description] do
30
+ example.run
31
+ end
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,234 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Avinash Dwarapu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: vcr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: faraday
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 0.9.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 0.9.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: memoizable
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: oj
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: A Reddit API Wrapper for Ruby.
154
+ email:
155
+ - d.nash.avi@gmail.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - .gitignore
161
+ - .rspec
162
+ - .rubocop.yml
163
+ - .travis.yml
164
+ - .yardopts
165
+ - Gemfile
166
+ - LICENSE.txt
167
+ - README.md
168
+ - Rakefile
169
+ - github/redd.png
170
+ - lib/redd.rb
171
+ - lib/redd/RedditKit.LICENSE.md
172
+ - lib/redd/base.rb
173
+ - lib/redd/client/authenticated.rb
174
+ - lib/redd/client/authenticated/account.rb
175
+ - lib/redd/client/authenticated/apps.rb
176
+ - lib/redd/client/authenticated/flair.rb
177
+ - lib/redd/client/authenticated/gold.rb
178
+ - lib/redd/client/authenticated/links_comments.rb
179
+ - lib/redd/client/authenticated/live.rb
180
+ - lib/redd/client/authenticated/moderation.rb
181
+ - lib/redd/client/authenticated/multis.rb
182
+ - lib/redd/client/authenticated/private_messages.rb
183
+ - lib/redd/client/authenticated/subreddits.rb
184
+ - lib/redd/client/authenticated/users.rb
185
+ - lib/redd/client/authenticated/wiki.rb
186
+ - lib/redd/client/oauth2.rb
187
+ - lib/redd/client/unauthenticated.rb
188
+ - lib/redd/client/unauthenticated/account.rb
189
+ - lib/redd/client/unauthenticated/links_comments.rb
190
+ - lib/redd/client/unauthenticated/listing.rb
191
+ - lib/redd/client/unauthenticated/subreddits.rb
192
+ - lib/redd/client/unauthenticated/utilities.rb
193
+ - lib/redd/client/unauthenticated/wiki.rb
194
+ - lib/redd/error.rb
195
+ - lib/redd/object/comment.rb
196
+ - lib/redd/object/listing.rb
197
+ - lib/redd/object/submission.rb
198
+ - lib/redd/object/subreddit.rb
199
+ - lib/redd/rate_limit.rb
200
+ - lib/redd/response/parse_json.rb
201
+ - lib/redd/response/raise_error.rb
202
+ - lib/redd/thing.rb
203
+ - lib/redd/version.rb
204
+ - redd.gemspec
205
+ - spec/redd_spec.rb
206
+ - spec/spec_helper.rb
207
+ homepage: ''
208
+ licenses:
209
+ - MIT
210
+ metadata: {}
211
+ post_install_message:
212
+ rdoc_options: []
213
+ require_paths:
214
+ - lib
215
+ required_ruby_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - '>='
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ required_rubygems_version: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - '>='
223
+ - !ruby/object:Gem::Version
224
+ version: '0'
225
+ requirements: []
226
+ rubyforge_project:
227
+ rubygems_version: 2.0.14
228
+ signing_key:
229
+ specification_version: 4
230
+ summary: A Reddit API Wrapper for Ruby.
231
+ test_files:
232
+ - spec/redd_spec.rb
233
+ - spec/spec_helper.rb
234
+ has_rdoc: