bterlson-reddit 0.2.1 → 0.3.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.
- data/lib/reddit/article.rb +4 -2
- data/lib/reddit/comment.rb +4 -2
- data/lib/reddit/comment_list.rb +4 -9
- data/lib/reddit/reddit.rb +21 -17
- data/lib/reddit/resource_list.rb +25 -11
- data/lib/reddit/session.rb +1 -1
- data/lib/reddit/user.rb +5 -8
- data/lib/reddit/version.rb +2 -2
- data/spec/article_spec.rb +1 -1
- data/spec/comment_list_spec.rb +2 -6
- data/spec/reddit_spec.rb +13 -8
- data/spec/resource_list_spec.rb +13 -2
- data/spec/user_spec.rb +1 -7
- metadata +3 -3
- data/README.txt +0 -66
data/lib/reddit/article.rb
CHANGED
@@ -15,6 +15,7 @@ module Reddit
|
|
15
15
|
@domain = attributes['domain']
|
16
16
|
@author = User.new(attributes['author']) unless attributes['author'].nil?
|
17
17
|
@id = attributes['id']
|
18
|
+
# Reddit's created_at timestamps are currently wonky, so this will return the wrong time.
|
18
19
|
@created_at = Time.at(attributes['created']) unless attributes['created'].nil?
|
19
20
|
@saved = attributes['saved']
|
20
21
|
@clicked = attributes['clicked']
|
@@ -37,8 +38,9 @@ module Reddit
|
|
37
38
|
end
|
38
39
|
|
39
40
|
# returns a CommentList of this article's comments.
|
40
|
-
def comments
|
41
|
-
|
41
|
+
def comments(options = {})
|
42
|
+
@comments_list ||= CommentList.new(@id)
|
43
|
+
return @comments_list.top_level(options)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
data/lib/reddit/comment.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Reddit
|
2
|
-
|
3
2
|
# A reddit comment.
|
4
3
|
class Comment
|
5
4
|
attr_reader :body, :name, :ups, :downs, :url, :domain, :author, :id, :created_at, :replies
|
@@ -21,7 +20,6 @@ module Reddit
|
|
21
20
|
@replies << Comment.new(reply['data'])
|
22
21
|
end
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
24
|
|
27
25
|
# Returns the score for this comment.
|
@@ -29,5 +27,9 @@ module Reddit
|
|
29
27
|
return @ups - @downs
|
30
28
|
end
|
31
29
|
|
30
|
+
# returns a number representing how controversial this comment is
|
31
|
+
def controversy_score
|
32
|
+
(@ups + @downs).to_f / [score.abs, 1].max
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/reddit/comment_list.rb
CHANGED
@@ -10,15 +10,10 @@ module Reddit
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# returns the top level comments for the thread.
|
13
|
-
def top_level
|
14
|
-
|
15
|
-
|
16
|
-
comments = []
|
17
|
-
resources.each do |comment|
|
18
|
-
comments << Comment.new(comment['data'])
|
13
|
+
def top_level(options = {})
|
14
|
+
get_resources(@url, :querystring => options[:querystring], :count => options[:count]) do |resource_json|
|
15
|
+
comment = Comment.new(resource_json['data'])
|
19
16
|
end
|
20
|
-
|
21
|
-
return comments
|
22
17
|
end
|
23
18
|
|
24
19
|
private
|
@@ -26,6 +21,6 @@ module Reddit
|
|
26
21
|
# forward any method calls to the top level comments array.
|
27
22
|
def method_missing(meth, *args, &block)
|
28
23
|
top_level.send(meth, *args, &block)
|
29
|
-
end
|
24
|
+
end
|
30
25
|
end
|
31
26
|
end
|
data/lib/reddit/reddit.rb
CHANGED
@@ -9,33 +9,37 @@ module Reddit
|
|
9
9
|
@url = @name.nil? ? BASE_URL : SUBREDDIT_URL.gsub('[subreddit]', @name)
|
10
10
|
end
|
11
11
|
|
12
|
-
def hot
|
13
|
-
articles 'hot'
|
12
|
+
def hot(options = {})
|
13
|
+
articles 'hot', options
|
14
14
|
end
|
15
15
|
|
16
|
-
def top
|
17
|
-
articles 'top'
|
16
|
+
def top(options = {})
|
17
|
+
articles 'top', options
|
18
18
|
end
|
19
19
|
|
20
|
-
def new
|
21
|
-
|
20
|
+
def new(options = {})
|
21
|
+
options[:querystring] = 'sort=new'
|
22
|
+
articles 'new', options
|
22
23
|
end
|
23
24
|
|
24
|
-
def
|
25
|
-
|
25
|
+
def rising(options = {})
|
26
|
+
options[:querystring] = 'sort=rising'
|
27
|
+
articles 'new', options
|
28
|
+
end
|
29
|
+
|
30
|
+
def controversial(options = {})
|
31
|
+
articles 'controversial', options
|
26
32
|
end
|
27
33
|
|
28
34
|
# Returns the articles found in this reddit.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
# Options are:
|
36
|
+
# Count: Return at least this many articles.
|
37
|
+
# Querystring: Querystring to append to resource request
|
38
|
+
|
39
|
+
def articles(page = 'hot', options = {})
|
40
|
+
get_resources("#{@url}#{page}", options) do |resource_json|
|
41
|
+
Article.new(resource_json['data'])
|
36
42
|
end
|
37
|
-
|
38
|
-
return articles
|
39
43
|
end
|
40
44
|
end
|
41
45
|
end
|
data/lib/reddit/resource_list.rb
CHANGED
@@ -7,22 +7,36 @@ module Reddit
|
|
7
7
|
private
|
8
8
|
|
9
9
|
# Grabs the resources at the URL and returns the parsed json.
|
10
|
-
def get_resources(url)
|
11
|
-
|
10
|
+
def get_resources(url, options = {}, &block)
|
11
|
+
querystring = options.delete(:querystring) || ''
|
12
|
+
count = options.delete(:count) || 25
|
12
13
|
url = URI.parse(url)
|
14
|
+
items = []
|
15
|
+
after = ''
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
while items.size < count
|
18
|
+
res = Net::HTTP.start(url.host, url.port) {|http|
|
19
|
+
http.get("#{url.path}.json?#{querystring}&after=#{after}&limit=#{count - items.size}")
|
20
|
+
}
|
17
21
|
|
18
|
-
|
19
|
-
resources = JSON.parse(res.body, :max_nesting => 0)
|
22
|
+
raise SubredditNotFound if res.is_a?(Net::HTTPRedirection)
|
20
23
|
|
21
|
-
|
22
|
-
# and the second is the actual comments. This is hackish.
|
23
|
-
resources = resources.last if resources.is_a?(Array)
|
24
|
+
resources = JSON.parse(res.body, :max_nesting => 0)
|
24
25
|
|
25
|
-
|
26
|
+
# comments pages are contained in an array where the first element is the article
|
27
|
+
# and the second is the actual comments. This is hackish.
|
28
|
+
resources = resources.last if resources.is_a?(Array)
|
29
|
+
resources = resources['data']['children']
|
30
|
+
break if resources.size == 0
|
31
|
+
resources.each do |resource|
|
32
|
+
items << yield(resource)
|
33
|
+
end
|
34
|
+
|
35
|
+
after = items.last.name
|
36
|
+
end
|
37
|
+
|
38
|
+
items
|
26
39
|
end
|
27
40
|
end
|
41
|
+
|
28
42
|
end
|
data/lib/reddit/session.rb
CHANGED
@@ -2,7 +2,7 @@ module Reddit
|
|
2
2
|
BASE_URL = "http://www.reddit.com/"
|
3
3
|
PROFILE_URL = BASE_URL + "user/[username]/"
|
4
4
|
SUBREDDIT_URL = BASE_URL + "r/[subreddit]/"
|
5
|
-
COMMENTS_URL = BASE_URL + "
|
5
|
+
COMMENTS_URL = BASE_URL + "comments/[id]/"
|
6
6
|
|
7
7
|
# raised when attempting to interact with a subreddit that doesn't exist.
|
8
8
|
class SubredditNotFound < StandardError; end
|
data/lib/reddit/user.rb
CHANGED
@@ -11,15 +11,12 @@ module Reddit
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# Get the user's comments.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
comments
|
18
|
-
|
19
|
-
comments << Comment.new(comment['data'])
|
14
|
+
# Options can include a limit, which sets the number of comments to return.
|
15
|
+
|
16
|
+
def comments(options = {})
|
17
|
+
get_resources("#{@url}comments/", :querystring => options[:querystring], :count => options[:count]) do |resource_json|
|
18
|
+
Comment.new(resource_json['data'])
|
20
19
|
end
|
21
|
-
|
22
|
-
return comments
|
23
20
|
end
|
24
21
|
end
|
25
22
|
end
|
data/lib/reddit/version.rb
CHANGED
data/spec/article_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Reddit::Article do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it "should be able to get the article's comments comments" do
|
9
|
-
Reddit::CommentList.should_receive(:new).with("id").and_return("reddit!")
|
9
|
+
Reddit::CommentList.should_receive(:new).with("id").and_return(mock(Reddit::CommentList, :top_level => "reddit!"))
|
10
10
|
@article.comments.should == "reddit!"
|
11
11
|
end
|
12
12
|
end
|
data/spec/comment_list_spec.rb
CHANGED
@@ -10,13 +10,9 @@ describe Reddit::CommentList do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should fetch the top level comments" do
|
13
|
-
@comments_list.should_receive(:get_resources).and_return([
|
14
|
-
{:type => 't1', :data => {:attribute => 'value'}},
|
15
|
-
{:type => 't1', :data => {:attribute => 'value2'}}
|
16
|
-
])
|
17
|
-
|
18
13
|
mock_comment = mock(Reddit::Comment)
|
19
|
-
|
14
|
+
|
15
|
+
@comments_list.should_receive(:get_resources).and_return([mock_comment, mock_comment])
|
20
16
|
|
21
17
|
@comments_list.top_level.should == [mock_comment, mock_comment]
|
22
18
|
end
|
data/spec/reddit_spec.rb
CHANGED
@@ -17,18 +17,15 @@ describe Reddit::Reddit do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should find the articles" do
|
20
|
-
@reddit.should_receive(:get_resources).and_return(test_articles)
|
21
|
-
|
22
20
|
mock_article = mock(Reddit::Article)
|
23
|
-
|
24
|
-
|
21
|
+
@reddit.should_receive(:get_resources).and_return([mock_article, mock_article])
|
25
22
|
@reddit.articles.should == [mock_article, mock_article]
|
26
23
|
end
|
27
24
|
|
28
25
|
it "should find top articles" do
|
29
26
|
mock_article = mock(Reddit::Article)
|
30
27
|
|
31
|
-
@reddit.should_receive(:articles).with('top').and_return([mock_article, mock_article])
|
28
|
+
@reddit.should_receive(:articles).with('top', {}).and_return([mock_article, mock_article])
|
32
29
|
|
33
30
|
@reddit.top.should == [mock_article, mock_article]
|
34
31
|
end
|
@@ -36,15 +33,23 @@ describe Reddit::Reddit do
|
|
36
33
|
it "should find new articles" do
|
37
34
|
mock_article = mock(Reddit::Article)
|
38
35
|
|
39
|
-
@reddit.should_receive(:articles).with('new').and_return([mock_article, mock_article])
|
36
|
+
@reddit.should_receive(:articles).with('new', {:querystring => 'sort=new'}).and_return([mock_article, mock_article])
|
40
37
|
|
41
38
|
@reddit.new.should == [mock_article, mock_article]
|
42
39
|
end
|
43
40
|
|
41
|
+
it "should find rising articles" do
|
42
|
+
mock_article = mock(Reddit::Article)
|
43
|
+
|
44
|
+
@reddit.should_receive(:articles).with('new', {:querystring => 'sort=rising'}).and_return([mock_article, mock_article])
|
45
|
+
|
46
|
+
@reddit.rising.should == [mock_article, mock_article]
|
47
|
+
end
|
48
|
+
|
44
49
|
it "should find controversial articles" do
|
45
50
|
mock_article = mock(Reddit::Article)
|
46
51
|
|
47
|
-
@reddit.should_receive(:articles).with('controversial').and_return([mock_article, mock_article])
|
52
|
+
@reddit.should_receive(:articles).with('controversial', {}).and_return([mock_article, mock_article])
|
48
53
|
|
49
54
|
@reddit.controversial.should == [mock_article, mock_article]
|
50
55
|
end
|
@@ -52,7 +57,7 @@ describe Reddit::Reddit do
|
|
52
57
|
it "should find hot articles" do
|
53
58
|
mock_article = mock(Reddit::Article)
|
54
59
|
|
55
|
-
@reddit.should_receive(:articles).with('hot').and_return([mock_article, mock_article])
|
60
|
+
@reddit.should_receive(:articles).with('hot', {}).and_return([mock_article, mock_article])
|
56
61
|
|
57
62
|
@reddit.hot.should == [mock_article, mock_article]
|
58
63
|
end
|
data/spec/resource_list_spec.rb
CHANGED
@@ -12,12 +12,23 @@ describe Reddit::ResourceList, ".get_resources" do
|
|
12
12
|
|
13
13
|
it "should get the resources from Reddit" do
|
14
14
|
Net::HTTP.should_receive(:start).and_yield(@http_mock).and_return(@response_mock)
|
15
|
-
@resource_list.send(:get_resources, "http://reddit.com")
|
15
|
+
@resource_list.send(:get_resources, "http://reddit.com", :count => 1) do
|
16
|
+
mock('object', :name => "object_name")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should get the specified number of resources" do
|
21
|
+
Net::HTTP.should_receive(:start).exactly(:twice).and_yield(@http_mock).and_return(@response_mock)
|
22
|
+
@resource_list.send(:get_resources, "http://reddit.com", :count => 2) do
|
23
|
+
mock('object', :name => "object_name")
|
24
|
+
end
|
16
25
|
end
|
17
26
|
|
18
27
|
it "should parse the JSON" do
|
19
28
|
JSON.should_receive(:parse).and_return({'kind' => 'Listing', 'data' => {'children' => [{'data' => {'attribute' => 'value'}}]}})
|
20
|
-
@resource_list.send(:get_resources, "http://reddit.com")
|
29
|
+
@resource_list.send(:get_resources, "http://reddit.com", :count => 1) do
|
30
|
+
mock('object', :name => "object_name")
|
31
|
+
end
|
21
32
|
end
|
22
33
|
|
23
34
|
it "should raise an error when the subreddit is not found" do
|
data/spec/user_spec.rb
CHANGED
@@ -10,14 +10,8 @@ describe Reddit::User do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should fetch the user's comments" do
|
13
|
-
@user.should_receive(:get_resources).and_return([
|
14
|
-
{:type => 't1', :data => {:attribute => 'value'}},
|
15
|
-
{:type => 't1', :data => {:attribute => 'value2'}}
|
16
|
-
])
|
17
|
-
|
18
13
|
mock_comment = mock(Reddit::Comment)
|
19
|
-
|
20
|
-
|
14
|
+
@user.should_receive(:get_resources).and_return([mock_comment, mock_comment])
|
21
15
|
@user.comments.should == [mock_comment, mock_comment]
|
22
16
|
end
|
23
17
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bterlson-reddit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Terlson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-08-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -77,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
77
|
requirements: []
|
78
78
|
|
79
79
|
rubyforge_project:
|
80
|
-
rubygems_version: 1.0
|
80
|
+
rubygems_version: 1.2.0
|
81
81
|
signing_key:
|
82
82
|
specification_version: 2
|
83
83
|
summary: Interface with the Reddit.com API.
|
data/README.txt
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
= reddit
|
2
|
-
|
3
|
-
* http://github.com/bterlson/reddit/
|
4
|
-
|
5
|
-
== DESCRIPTION:
|
6
|
-
|
7
|
-
An interface to the reddit API.
|
8
|
-
|
9
|
-
== FEATURES/PROBLEMS:
|
10
|
-
|
11
|
-
* Retreive articles and their comments
|
12
|
-
* Retreive user pages
|
13
|
-
|
14
|
-
== SYNOPSIS:
|
15
|
-
|
16
|
-
require 'rubygems'
|
17
|
-
require 'reddit'
|
18
|
-
|
19
|
-
reddit = Reddit::Session.new
|
20
|
-
|
21
|
-
reddit.main.articles.each do |article|
|
22
|
-
p article.url
|
23
|
-
|
24
|
-
article.comments.each do |comment|
|
25
|
-
p comment.body
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
p reddit.subreddit("programming").articles[1].author
|
30
|
-
|
31
|
-
reddit.user("radhruin").comments.each do |comment|
|
32
|
-
p comment.body
|
33
|
-
end
|
34
|
-
|
35
|
-
== REQUIREMENTS:
|
36
|
-
|
37
|
-
* JSON >= 1.1.2
|
38
|
-
|
39
|
-
== INSTALL:
|
40
|
-
|
41
|
-
* sudo gem install bterlson-reddit --source=http://gems.github.com
|
42
|
-
|
43
|
-
== LICENSE:
|
44
|
-
|
45
|
-
(The MIT License)
|
46
|
-
|
47
|
-
Copyright (c) 2008 FIX
|
48
|
-
|
49
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
50
|
-
a copy of this software and associated documentation files (the
|
51
|
-
'Software'), to deal in the Software without restriction, including
|
52
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
53
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
54
|
-
permit persons to whom the Software is furnished to do so, subject to
|
55
|
-
the following conditions:
|
56
|
-
|
57
|
-
The above copyright notice and this permission notice shall be
|
58
|
-
included in all copies or substantial portions of the Software.
|
59
|
-
|
60
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
61
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
62
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
63
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
64
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
65
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
66
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|