ruby_reddit_api 0.1.9

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/README ADDED
@@ -0,0 +1,47 @@
1
+ Ruby Reddit Client v0.1.9
2
+ ==================
3
+ Tested with 1.9.2
4
+
5
+ Usage:
6
+ =======
7
+ > require "ruby_reddit_api"
8
+ > r = Reddit::Api.new "user", "password"
9
+ > results = r.browse "ruby"
10
+ > results[0].upvote
11
+
12
+ Features:
13
+ ========
14
+ - Authentication
15
+ - Parse submissions
16
+ - Comments parsing
17
+ - Vote on submission
18
+
19
+
20
+ Running Tests:
21
+ =============
22
+ - Set up the reddit VM (http://blog.reddit.com/2010/05/admins-never-do-what-you-want-now-it-is.html)
23
+ - Ensure your hosts file has reddit.local pointing to the VM
24
+ - rake cucumber
25
+
26
+ License
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2010 James Cook
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ of this software and associated documentation files (the "Software"), to deal
33
+ in the Software without restriction, including without limitation the rights
34
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ copies of the Software, and to permit persons to whom the Software is
36
+ furnished to do so, subject to the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be included in
39
+ all copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
+ THE SOFTWARE.
@@ -0,0 +1,10 @@
1
+ Feature: Browsing
2
+ I want to be able to browse submissions
3
+
4
+ Scenario: Valid subreddit
5
+ Given I submit a valid subreddit
6
+ Then I should get back a listing of submissions
7
+
8
+ Scenario: Invalid subreddit
9
+ Given I submit a invalid subreddit
10
+ Then I should get back some error
@@ -0,0 +1,15 @@
1
+ Feature: Authentication
2
+ In order perform things like voting and commenting
3
+ As a Redditor
4
+ I want to be able to login in my step definitions
5
+
6
+ Scenario: Valid user and password
7
+ Given I have a valid user
8
+ And I send my user and password to the login API
9
+ Then I should have a valid cookie
10
+ And the stored headers should refer to the cookie
11
+
12
+ Scenario: Invalid user and password
13
+ Given I have a invalid user
14
+ And I send my user and password to the login API
15
+ Then I should not have a valid cookie
@@ -0,0 +1,40 @@
1
+ Feature: Comments
2
+ I want to be able to comment on a comment
3
+ I want to be able to delete my comments
4
+
5
+ Scenario: Valid comment text
6
+ Given I enter some text
7
+ Then I should be able to add a comment
8
+
9
+ Scenario: I want to hide a comment
10
+ Given I have a comment
11
+ Then I should be able to hide the comment
12
+
13
+ Scenario: I want to remove a comment
14
+ Given I have a comment
15
+ Then I should be able to remove the comment
16
+
17
+ Scenario: I want to approve a comment
18
+ Given I have a comment
19
+ Then I should be able to approve the comment
20
+
21
+ Scenario: I want to edit a comment
22
+ Given I have a comment
23
+ Then I should be able to edit the comment
24
+
25
+ Scenario: I want to comment on a comment
26
+ Given I have a comment
27
+ Then I should be able to reply to the comment
28
+
29
+ Scenario: I want to moderator distinguish a comment
30
+ Given I have a comment
31
+ Then I should be able to moderator distinguish the comment
32
+
33
+ Scenario: I want to indistinguish a comment
34
+ Given I have a comment
35
+ Then I should be able to indistinguish the comment
36
+
37
+ Scenario: I want to admin distinguish a comment
38
+ Given I have a comment
39
+ Then I should be able to admin distinguish the comment
40
+
@@ -0,0 +1,5 @@
1
+ Feature: Messaging
2
+ Scenario: I want to be able to read my sent messages
3
+ Given I am logged in
4
+ When I go to the sent messages page
5
+ Then I should see a listing of messages
@@ -0,0 +1,5 @@
1
+ server:
2
+ address: "reddit.local"
3
+ port: 80
4
+ test_user: "reddit"
5
+ test_pass: "password"
@@ -0,0 +1,22 @@
1
+ Given /^I submit a valid subreddit$/ do
2
+ Reddit::Api.base_uri "reddit.local"
3
+ @api = Reddit::Api.new "reddit", "password"
4
+ @subreddit = "reddit_test0"
5
+ end
6
+
7
+ Then /^I should get back a listing of submissions$/ do
8
+ results = @api.browse(@subreddit)
9
+ results[0].class.should == Reddit::Submission
10
+ results[0].author.should_not == nil
11
+ end
12
+
13
+ Given /^I submit a invalid subreddit$/ do
14
+ Reddit::Api.base_uri "reddit.local"
15
+ @api = Reddit::Api.new "reddit", "password"
16
+ @subreddit = "invalid_subreddit"
17
+ end
18
+
19
+ Then /^I should get back some error$/ do
20
+ results = @api.browse(@subreddit)
21
+ results.should == false
22
+ end
@@ -0,0 +1,49 @@
1
+ require File.join( File.dirname(__FILE__), "..", "..", "lib", "ruby_reddit_api.rb")
2
+ Before do
3
+ Reddit::Base.instance_variable_set("@cookie", nil)
4
+ load_server_config
5
+ Reddit::Api.base_uri @address
6
+ end
7
+
8
+ Given /^I have a valid user$/ do
9
+ load_server_config
10
+ end
11
+
12
+ Given /^I have a invalid user$/ do
13
+ @user, @pass = "invalid", "user"
14
+ end
15
+
16
+ Given /^I send my user and password to the login API$/ do
17
+ @api = Reddit::Api.new @user, @pass
18
+ @api.login
19
+ end
20
+
21
+ Given /I'm logged in$/ do
22
+ @api = Reddit::Api.new @user, @pass
23
+ @api.login
24
+ end
25
+
26
+ Given /I'm not logged in$/ do
27
+ @api.logout if @api
28
+ @api = Reddit::Api.new @user, "bad pass"
29
+ @api.logout
30
+ end
31
+
32
+ Then /^I should have a valid cookie$/ do
33
+ @api.cookie.should_not == nil
34
+ @api.cookie.should =~ /reddit_session/
35
+ end
36
+
37
+ Then /^I should not have a valid cookie$/ do
38
+ @api.cookie.should_not == nil
39
+ @api.cookie.should =~ /reddit_first/
40
+ end
41
+
42
+ Then /^I should not have a cookie$/ do
43
+ @api.cookie.should == nil
44
+ end
45
+
46
+ Then /^the stored headers should refer to the cookie$/ do
47
+ @api.base_headers["Cookie"].should == @api.cookie
48
+ end
49
+
@@ -0,0 +1,59 @@
1
+ Before do
2
+ load_server_config
3
+ Reddit::Api.base_uri @address
4
+ Reddit::Submission.base_uri @address
5
+ Reddit::Comment.base_uri @address
6
+ @api = Reddit::Api.new @user, @pass
7
+ @api.login
8
+ @submission ||= @api.browse("reddit_test0")[0]
9
+ end
10
+
11
+ Given /^I enter some text$/ do
12
+ @text = "SOME COMMENT"
13
+ end
14
+
15
+ Then /^I should be able to add a comment$/ do
16
+ @submission.add_comment(@text).should be true
17
+ end
18
+
19
+ Given /^I have a comment$/ do
20
+ @submission.add_comment("a comment")
21
+ @comment = @submission.comments.last
22
+ end
23
+
24
+ Then /^I should be able to hide the comment$/ do
25
+ @comment.hide
26
+ end
27
+
28
+ Then /^I should be able to remove the comment$/ do
29
+ @comment.remove
30
+ end
31
+
32
+ Then /^I should be able to approve the comment$/ do
33
+ @comment.approve
34
+ end
35
+
36
+ Then /^I should not be able to edit the comment$/ do
37
+ @comment.edit( "1234" ).should be false
38
+ end
39
+
40
+ Then /^I should be able to edit the comment$/ do
41
+ @comment.edit( "1234" ).should be true
42
+ end
43
+
44
+ Then /^I should be able to moderator distinguish the comment$/ do
45
+ pending #@comment.moderator_distinguish
46
+ end
47
+
48
+ Then /^I should be able to indistinguish the comment$/ do
49
+ pending #@comment.indistinguish
50
+ end
51
+
52
+ Then /^I should be able to admin distinguish the comment$/ do
53
+ pending #@comment.admin_distinguish
54
+ end
55
+
56
+ Then /^I should be able to reply to the comment$/ do
57
+ pending #@comment.reply("a reply").should be true
58
+ end
59
+
@@ -0,0 +1,18 @@
1
+ Before do
2
+ load_server_config
3
+ Reddit::Api.base_uri @address
4
+ Reddit::Message.base_uri @address
5
+ end
6
+
7
+ Given /^I am logged in$/ do
8
+ @api = Reddit::Api.new @user, @pass
9
+ @api.login
10
+ end
11
+
12
+ When /^I go to the sent messages page$/ do
13
+ @result = @api.sent_messages
14
+ end
15
+
16
+ Then /^I should see a listing of messages$/ do
17
+ @result.any?{|r| r.is_a?(Reddit::Message) == false}.should be false
18
+ end
@@ -0,0 +1,117 @@
1
+ Given /^I have a submission$/ do
2
+ load_server_config
3
+ Reddit::Api.base_uri @address
4
+ Reddit::Submission.base_uri @address
5
+ Reddit::Comment.base_uri @address
6
+ @api = Reddit::Api.new @user, @pass
7
+ @api.login
8
+ @submission = @api.browse("reddit_test0")[0]
9
+ if @api.logged_in?
10
+ @submission.add_comment("STOP REPOSTING!!1") if @submission
11
+ else
12
+ raise "Can't run test. Submit failed.."
13
+ end
14
+ end
15
+
16
+ Then /^I should be able to see the author$/ do
17
+ @submission.author.should_not == nil
18
+ end
19
+
20
+ Then /^I should be able to see the title$/ do
21
+ @submission.title.should_not == nil
22
+ end
23
+
24
+ Then /^I should be able to see the selftext$/ do
25
+ @submission.selftext.should_not == nil
26
+ end
27
+
28
+ Then /^I should be able to see the url$/ do
29
+ @submission.url.should_not == nil
30
+ end
31
+
32
+ Then /^I should be able to see the up votes$/ do
33
+ @submission.ups.should_not == nil
34
+ end
35
+
36
+ Then /^I should be able to see the down votes$/ do
37
+ @submission.downs.should_not == nil
38
+ end
39
+
40
+ Then /^I should not be able to upvote it$/ do
41
+ @submission.upvote.should be false
42
+ end
43
+
44
+ Then /^I should not be able to downvote it$/ do
45
+ @submission.downvote.should be false
46
+ end
47
+
48
+ Then /^I should be able to upvote it$/ do
49
+ @submission.upvote.should be true
50
+ end
51
+
52
+ Then /^I should be able to downvote it$/ do
53
+ @submission.downvote.should be true
54
+ end
55
+
56
+ Then /^I should be able to see the comments$/ do
57
+ comments = @submission.comments
58
+ comments.size.should > 0
59
+ end
60
+
61
+ Then /^I should not be able to save the submission$/ do
62
+ @submission.save.should be false
63
+ end
64
+
65
+ Then /^I should not be able to unsave the submission$/ do
66
+ @submission.unsave.should be false
67
+ end
68
+
69
+ Then /^I should not be able to hide the submission$/ do
70
+ @submission.hide.should be false
71
+ end
72
+
73
+ Then /^I should not be able to unhide the submission$/ do
74
+ @submission.unhide.should be false
75
+ end
76
+
77
+ Then /^I should be able to save the submission$/ do
78
+ @submission.save.should be true
79
+ end
80
+
81
+ Then /^I should be able to unsave the submission$/ do
82
+ @submission.unsave.should be true
83
+ end
84
+
85
+ Then /^I should be able to hide the submission$/ do
86
+ result = @submission.hide
87
+ @submission.unhide if result
88
+ result.should be true
89
+ end
90
+
91
+ Then /^I should be able to unhide the submission$/ do
92
+ @submission.unhide.should be true
93
+ end
94
+
95
+ Then /^I should be able to report the submission$/ do
96
+ @submission.report.should be true
97
+ end
98
+
99
+ Then /^I should not be able to report the submission$/ do
100
+ @submission.report.should be false
101
+ end
102
+
103
+ Then /^I should be able to see more comments if needed$/ do
104
+ pending
105
+ end
106
+
107
+ Then /^I should be able to moderator distinguish the submission$/ do
108
+ @submission.moderator_distinguish
109
+ end
110
+
111
+ Then /^I should be able to admin distinguish the submission$/ do
112
+ @submission.admin_distinguish
113
+ end
114
+
115
+ Then /^I should be able to indistinguish the submission$/ do
116
+ @submission.indistinguish
117
+ end
@@ -0,0 +1,25 @@
1
+ Before do
2
+ load_server_config
3
+ Reddit::Api.base_uri @address
4
+ Reddit::Submission.base_uri @address
5
+ Reddit::Comment.base_uri @address
6
+ Reddit::User.base_uri @address
7
+ @api = Reddit::Api.new @user, @pass
8
+ @api.login
9
+ end
10
+
11
+ Given /^I select a redditor$/ do
12
+ @submission = @api.browse("reddit_test1")[0]
13
+ @user = @submission.author
14
+ end
15
+
16
+ Then /^I should be able to friend them$/ do
17
+ @user.friend.should be true
18
+ end
19
+
20
+ Then /^I should be able to unfriend them$/ do
21
+ @user.unfriend.should be true
22
+ end
23
+
24
+
25
+
@@ -0,0 +1,58 @@
1
+ Feature: Submissions
2
+ I want to be able to peruse the submission details
3
+ And I want to be able to up vote the submission
4
+ And I want to be able to down vote the submission
5
+ And I want to be able to save submissions I like
6
+ And I want to be able to unsave submissions
7
+
8
+
9
+ Scenario: Viewing a submission
10
+ Scenario: When not logged in
11
+ Given I have a submission
12
+ And I'm not logged in
13
+ Then I should be able to see the author
14
+ And I should be able to see the title
15
+ And I should be able to see the selftext
16
+ And I should be able to see the url
17
+ And I should be able to see the up votes
18
+ And I should be able to see the down votes
19
+ And I should be able to see the comments
20
+ But I should not be able to upvote it
21
+ But I should not be able to downvote it
22
+ But I should not be able to save the submission
23
+ But I should not be able to unsave the submission
24
+ But I should not be able to hide the submission
25
+ But I should not be able to unhide the submission
26
+ But I should not be able to report the submission
27
+ And I should be able to see more comments if needed
28
+
29
+ Scenario: When logged in
30
+ Given I have a submission
31
+ And I'm logged in
32
+ Then I should be able to see the author
33
+ And I should be able to see the title
34
+ And I should be able to see the selftext
35
+ And I should be able to see the url
36
+ And I should be able to see the up votes
37
+ And I should be able to see the down votes
38
+ And I should be able to see the comments
39
+ And I should be able to upvote it
40
+ And I should be able to downvote it
41
+ And I should be able to save the submission
42
+ And I should be able to unsave the submission
43
+ And I should be able to hide the submission
44
+ And I should be able to unhide the submission
45
+ And I should be able to report the submission
46
+ And I should be able to see more comments if needed
47
+
48
+ Scenario: I want to moderator distinguish a submission
49
+ Given I have a submission
50
+ Then I should be able to moderator distinguish the submission
51
+
52
+ Scenario: I want to admin distinguish a submission
53
+ Given I have a submission
54
+ Then I should be able to admin distinguish the submission
55
+
56
+ Scenario: I want to indistinguish a submission
57
+ Given I have a submission
58
+ Then I should be able to indistinguish the submission
@@ -0,0 +1,17 @@
1
+ module BaseHelpers
2
+ def load_server_config
3
+ @address, @post, @user, @pass = parse_config.compact
4
+ end
5
+
6
+ protected
7
+ def parse_config
8
+ file = File.exist?("features/reddit.yml") ? YAML.load_file("features/reddit.yml") : {}
9
+ server = file.fetch("server"){ server_defaults }
10
+ return [ server["address"], server["port"], server["test_user"], server["test_pass"] ]
11
+ end
12
+
13
+ def server_defaults
14
+ {"address" => "reddit.local", "port" => "80", "test_user" => "reddit", "test_pass" => "password"}
15
+ end
16
+ end
17
+ World(BaseHelpers)
@@ -0,0 +1,11 @@
1
+ @user
2
+ Feature: User
3
+ In order have friends
4
+ As a Redditor
5
+ I want to be able to add and remove them
6
+
7
+ Scenario: Valid user and password
8
+ Given I select a redditor
9
+ Then I should be able to friend them
10
+ And I should be able to unfriend them
11
+
@@ -0,0 +1,17 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ module Reddit
4
+ end
5
+
6
+ require "httparty"
7
+ require "json"
8
+ require "reddit/version"
9
+ require "reddit/base"
10
+ require "reddit/json_listing"
11
+ require "reddit/api"
12
+ require "reddit/user"
13
+ require "reddit/vote"
14
+ require "reddit/submission"
15
+ require "reddit/comment"
16
+ require "reddit/message"
17
+
@@ -0,0 +1,46 @@
1
+ module Reddit
2
+
3
+ class Api < Base
4
+ attr_reader :last_action, :debug
5
+
6
+ def initialize(user=nil,password=nil, options={})
7
+ @user = user
8
+ @password = password
9
+ @debug = StringIO.new
10
+ end
11
+
12
+ def inspect
13
+ "<Reddit::Api user='#{user}'>"
14
+ end
15
+
16
+ def browse(subreddit, options={})
17
+ subreddit = sanitize_subreddit(subreddit)
18
+ options.merge! :handler => "Submission"
19
+ if options[:limit]
20
+ options.merge!({:query => {:limit => options[:limit]}})
21
+ end
22
+ read("/r/#{subreddit}.json", options )
23
+ end
24
+
25
+ def sent_messages
26
+ messages :sent
27
+ end
28
+
29
+ def received_messages
30
+ messages :inbox
31
+ end
32
+
33
+ def comments
34
+ messages :comments
35
+ end
36
+
37
+ def post_replies
38
+ messages :selfreply
39
+ end
40
+
41
+ protected
42
+ def messages(kind)
43
+ read("/message/#{kind.to_s}.json", :handler => "Message")
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,109 @@
1
+ module Reddit
2
+ class Base
3
+ include HTTParty
4
+
5
+ attr_reader :last_action, :debug
6
+ base_uri "www.reddit.com"
7
+ class << self; attr_reader :cookie, :modhash, :user_id, :user, end
8
+
9
+ def initialize(options={})
10
+ @debug = StringIO.new
11
+ end
12
+
13
+ def inspect
14
+ "<Reddit::Base user='#{user}'>"
15
+ end
16
+
17
+ def login
18
+ capture_session(self.class.post( "/api/login", {:body => {:user => @user, :passwd => @password}, :debug_output => @debug} ) )
19
+ logged_in?
20
+ end
21
+
22
+ def logout
23
+ Reddit::Base.instance_variable_set("@cookie",nil)
24
+ end
25
+
26
+ def cookie
27
+ Reddit::Base.cookie
28
+ end
29
+
30
+ def modhash
31
+ Reddit::Base.modhash
32
+ end
33
+
34
+ def user_id
35
+ Reddit::Base.user_id
36
+ end
37
+
38
+ def user
39
+ Reddit::Base.user
40
+ end
41
+
42
+ def logged_in?
43
+ !!(cookie && (cookie =~ /reddit_session/) != nil)
44
+ end
45
+
46
+ def user_agent
47
+ self.class.user_agent
48
+ end
49
+
50
+ def base_headers
51
+ self.class.base_headers
52
+ end
53
+
54
+ def read(url, options={})
55
+ unless throttled?
56
+ @debug.rewind
57
+ verb = (options[:verb] || "get")
58
+ param_key = (verb == "get") ? :query : :body
59
+ resp = self.class.send( verb, url, {param_key => (options[param_key] || {}), :headers => base_headers, :debug_output => @debug})
60
+ if valid_response?(resp)
61
+ @last_action = Time.now
62
+ klass = Reddit.const_get(options[:handler] || "Submission")
63
+ resp = klass.parse( JSON.parse(resp.body, :max_nesting => 9_999) )
64
+ return resp
65
+ else
66
+ return false
67
+ end
68
+ end
69
+ end
70
+
71
+ protected
72
+ def valid_response?(response)
73
+ response.code == 200 && response.headers["content-type"].to_s =~ /json/
74
+ end
75
+
76
+ def capture_session(response)
77
+ cookies = response.headers["set-cookie"]
78
+ Reddit::Base.instance_variable_set("@cookie", cookies)
79
+ Reddit::Base.instance_variable_set("@user", @user)
80
+ end
81
+
82
+ def capture_user_id
83
+ return true if user_id
84
+ this_user = read("/user/#{user}/about.json", :handler => "User")
85
+ Reddit::Base.instance_variable_set("@user_id", this_user.id)
86
+ end
87
+
88
+ def throttled?
89
+ @last_action && ( ( Time.now - @last_action ) < 1.0 )
90
+ end
91
+
92
+ def sanitize_subreddit(subreddit)
93
+ subreddit.gsub!(/^\/?r\//,'')
94
+ subreddit.gsub!(/\.json\Z/,'')
95
+ subreddit
96
+ end
97
+
98
+ class << self
99
+
100
+ def base_headers
101
+ {'Cookie' => Reddit::Base.cookie.to_s, 'user-agent' => user_agent}
102
+ end
103
+
104
+ def user_agent
105
+ "Ruby Reddit Client v#{Reddit::VERSION}"
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,86 @@
1
+ module Reddit
2
+ class Comment < Api
3
+ include JsonListing
4
+ attr_reader :body, :subreddit_id, :name, :created, :downs, :author, :created_utc, :body_html, :link_id, :parent_id, :likes, :replies, :subreddit, :ups, :debug, :kind
5
+ def initialize(json)
6
+ parse(json)
7
+ @debug = StringIO.new
8
+ end
9
+
10
+ def inspect
11
+ "<Reddit::Comment author='#{@author}' body='#{short_body}'>"
12
+ end
13
+
14
+ def id
15
+ "#{kind}_#{@id}"
16
+ end
17
+
18
+ def author
19
+ @author_data ||= read("/user/#{@author}/about.json", :handler => "User")
20
+ end
21
+
22
+ def to_s
23
+ body
24
+ end
25
+
26
+ def edit(newtext)
27
+ resp=self.class.post("/api/editusertext", {:body => {:thing_id => id, :uh => modhash, :r => subreddit, :text => newtext }, :headers => base_headers, :debug_output => @debug })
28
+ resp.code == 200
29
+ end
30
+
31
+ def hide # soft delete?
32
+ resp=self.class.post("/api/del", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => "removed" }, :headers => base_headers, :debug_output => @debug })
33
+ resp.code == 200
34
+ end
35
+
36
+ def remove
37
+ resp=self.class.post("/api/remove", {:body => {:id => id, :uh => modhash, :r => subreddit}, :headers => base_headers, :debug_output => @debug })
38
+ resp.code == 200
39
+ end
40
+
41
+ def approve
42
+ resp=self.class.post("/api/approve", {:body => {:id => id, :uh => modhash, :r => subreddit}, :headers => base_headers, :debug_output => @debug })
43
+ resp.code == 200
44
+ end
45
+
46
+ def moderator_distinguish
47
+ add_distinction "yes"
48
+ end
49
+
50
+ def admin_distinguish
51
+ add_distinction "admin"
52
+ end
53
+
54
+ def indistinguish
55
+ add_distinction "no"
56
+ end
57
+
58
+ def reply(text)
59
+ resp = self.class.post("/api/comment", {:body => {:thing_id => id, :text => text, :uh => modhash, :r => subreddit }, :headers => base_headers, :debug_output => @debug })
60
+ resp.code == 200
61
+ end
62
+
63
+ def upvote
64
+ Vote.new(self).up
65
+ end
66
+
67
+ def downvote
68
+ Vote.new(self).down
69
+ end
70
+
71
+ def short_body
72
+ str = body.to_s
73
+ if str.size > 15
74
+ str[0..15] + "..."
75
+ else
76
+ body
77
+ end
78
+ end
79
+
80
+ def add_distinction(verb)
81
+ resp=self.class.post("/api/distinguish/#{verb}", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => "distinguishing..."}, :headers => base_headers, :debug_output => @debug })
82
+ puts resp.headers
83
+ resp.code == 200
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,38 @@
1
+ module Reddit
2
+ module JsonListing
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ base.send(:include, InstanceMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def parse(json)
10
+ results = []
11
+ if json.is_a?(Array)
12
+ json.each do |j|
13
+ results << parse(j)
14
+ end
15
+ else
16
+ data = json["data"]
17
+ Reddit::Base.instance_variable_set("@modhash", data["modhash"]) # Needed for api calls
18
+
19
+ children = data["children"]
20
+ children.each do |message|
21
+ kind = message["kind"]
22
+ message["data"]["kind"] = kind
23
+ results << self.new(message["data"])
24
+ end
25
+ end
26
+
27
+ return results.flatten
28
+ end
29
+ end
30
+ module InstanceMethods
31
+ def parse(json)
32
+ json.keys.each do |key|
33
+ instance_variable_set("@#{key}", json[key])
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ module Reddit
2
+ class Message < Base
3
+ include JsonListing
4
+ attr_reader :body, :was_comment, :kind, :first_message, :name, :created, :dest, :created_utc, :body_html, :subreddit, :parent_id, :context, :replies, :subject, :debug
5
+ def initialize(json)
6
+ parse(json)
7
+ @debug = StringIO.new
8
+ end
9
+
10
+ def id
11
+ "#{kind}_#{@id}"
12
+ end
13
+
14
+ def author
15
+ @author_data ||= read("/user/#{@author}/about.json", :handler => "User")
16
+ end
17
+
18
+ def inspect
19
+ "<Reddit::Message '#{short_body}'>"
20
+ end
21
+
22
+ def short_body
23
+ if body.size > 15
24
+ body[0..15]
25
+ else
26
+ body
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,99 @@
1
+ module Reddit
2
+ class Submission < Base
3
+ include JsonListing
4
+ attr_reader :domain, :media_embed, :subreddit, :selftext_html, :selftext, :likes, :saved, :clicked, :media, :score, :over_18, :hidden, :thumbnail, :subreddit_id, :downs, :is_self, :permalink, :name, :created, :url, :title, :created_utc, :num_comments, :ups, :kind, :last_comment_id
5
+
6
+ def initialize(data)
7
+ parse(data)
8
+ @debug = StringIO.new
9
+ end
10
+
11
+ def inspect
12
+ "<Reddit::Submission id='#{id}' author='#{@author}' title='#{title}'>"
13
+ end
14
+
15
+ def id
16
+ "#{kind}_#{@id}"
17
+ end
18
+
19
+ def author
20
+ @author_data ||= read("/user/#{@author}/about.json", :handler => "User")
21
+ end
22
+
23
+ def add_comment(text)
24
+ resp = self.class.post("/api/comment", {:body => {:thing_id => id, :text => text, :uh => modhash, :r => subreddit }, :headers => base_headers, :debug_output => @debug })
25
+ resp.code == 200
26
+ end
27
+
28
+ def upvote
29
+ Reddit::Vote.new(self).up
30
+ end
31
+
32
+ def downvote
33
+ Reddit::Vote.new(self).down
34
+ end
35
+
36
+ def save
37
+ toggle :save
38
+ end
39
+
40
+ def unsave
41
+ toggle :unsave
42
+ end
43
+
44
+ def hide
45
+ toggle :hide
46
+ end
47
+
48
+ def unhide
49
+ toggle :unhide
50
+ end
51
+
52
+ def report
53
+ toggle :report
54
+ end
55
+
56
+ def moderator_distinguish
57
+ add_distinction "yes"
58
+ end
59
+
60
+ def admin_distinguish
61
+ add_distinction "admin"
62
+ end
63
+
64
+ def indistinguish
65
+ add_distinction "no"
66
+ end
67
+
68
+ def comments(more=false)
69
+ #TODO Get morechildren to work correctly
70
+ if more && last_comment_id
71
+ opts = {:handler => "Comment",
72
+ :verb => "post",
73
+ :body =>
74
+ {:link_id => last_comment_id, :depth => 0, :r => subreddit, :uh => modhash, :renderstyle => "json", :pv_hex => "", :id => id}
75
+ }
76
+ return read("/api/morechildren", opts )
77
+
78
+ else
79
+ _comments = read( permalink + ".json", {:handler => "Comment", :query => {:limit => 50}} )
80
+ @last_comment_id = _comments.last.id if _comments && _comments.any?
81
+ return _comments
82
+ end
83
+ end
84
+
85
+ protected
86
+ def add_distinction(verb)
87
+ resp=self.class.post("/api/distinguish/#{verb}", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => "distinguishing..."}, :headers => base_headers, :debug_output => @debug })
88
+ resp.code == 200
89
+ end
90
+
91
+ def toggle(which)
92
+ return false unless logged_in?
93
+ mapping = {:save => "save", :unsave => "unsave", :hide => "hidden", :unhide => "unhidden", :report => "report"}
94
+ mode = mapping[which]
95
+ resp = self.class.post("/api/#{which}", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => mode }, :headers => base_headers, :debug_output => @debug })
96
+ resp.code == 200
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,47 @@
1
+
2
+ module Reddit
3
+ class User < Api
4
+ attr_reader :name, :debug, :created, :created_utc, :link_karma, :comment_karma, :is_mod, :has_mod_mail, :kind
5
+ def initialize(json)
6
+ @debug = StringIO.new
7
+ parse(json)
8
+ end
9
+
10
+ def inspect
11
+ "<Reddit::User name='#{name}'>"
12
+ end
13
+
14
+ def id
15
+ "#{kind}_#{@id}"
16
+ end
17
+
18
+ def to_s
19
+ name
20
+ end
21
+
22
+ def friend
23
+ capture_user_id
24
+ resp=self.class.post("/api/friend", {:body => {:name => name, :container => user_id, :type => "friend", :uh => modhash}, :headers => base_headers, :debug_output => @debug })
25
+ resp.code == 200
26
+ end
27
+
28
+ def unfriend
29
+ capture_user_id
30
+ resp=self.class.post("/api/unfriend", {:body => {:name => name, :container => user_id, :type => "friend", :uh => modhash}, :headers => base_headers, :debug_output => @debug })
31
+ resp.code == 200
32
+ end
33
+
34
+ protected
35
+ def parse(json)
36
+ json.keys.each do |key|
37
+ instance_variable_set("@#{key}", json[key])
38
+ end
39
+ end
40
+
41
+ def self.parse(json)
42
+ kind, data = json["kind"], json["data"]
43
+ data["kind"] = kind
44
+ return self.new(data)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module Reddit
2
+ VERSION = File.exist?("VERSION") ? File.read("VERSION").chomp : ""
3
+ end
@@ -0,0 +1,33 @@
1
+ module Reddit
2
+ class Vote < Base
3
+ attr_reader :submission
4
+
5
+ def initialize(submission)
6
+ @submission = submission
7
+ end
8
+
9
+ def up
10
+ vote(:up)
11
+ end
12
+
13
+ def down
14
+ vote(:down)
15
+ end
16
+
17
+ def inspect
18
+ "<Reddit::Vote>"
19
+ end
20
+
21
+ protected
22
+ def vote(direction)
23
+ return false unless logged_in?
24
+ up_or_down = direction == :up ? 1 : -1
25
+ resp = self.class.post( "/api/vote", {:body => {:id => submission.id, :dir => up_or_down, :uh => modhash}, :headers => base_headers})
26
+ if resp.code == 200
27
+ return true
28
+ else
29
+ return false
30
+ end
31
+ end
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_reddit_api
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 9
9
+ version: 0.1.9
10
+ platform: ruby
11
+ authors:
12
+ - James Cook
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-05 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: httparty
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: cucumber
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ description: Wraps many reddit API functions such as submission and comments browsing, voting, messaging, friending, and more.
47
+ email:
48
+ - jamecook@gmail.com
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files: []
54
+
55
+ files:
56
+ - lib/ruby_reddit_api.rb
57
+ - lib/ruby_reddit_api/user.rb
58
+ - lib/ruby_reddit_api/comment.rb
59
+ - lib/ruby_reddit_api/message.rb
60
+ - lib/ruby_reddit_api/version.rb
61
+ - lib/ruby_reddit_api/vote.rb
62
+ - lib/ruby_reddit_api/submission.rb
63
+ - lib/ruby_reddit_api/api.rb
64
+ - lib/ruby_reddit_api/json_listing.rb
65
+ - lib/ruby_reddit_api/base.rb
66
+ - README
67
+ - features/reddit.yml
68
+ - features/submission.feature
69
+ - features/comment.feature
70
+ - features/user.feature
71
+ - features/base.feature
72
+ - features/message.feature
73
+ - features/api.feature
74
+ - features/step_definitions/message_steps.rb
75
+ - features/step_definitions/submission_steps.rb
76
+ - features/step_definitions/api_steps.rb
77
+ - features/step_definitions/user_steps.rb
78
+ - features/step_definitions/comment_steps.rb
79
+ - features/step_definitions/base_steps.rb
80
+ - features/support/base_helpers.rb
81
+ has_rdoc: true
82
+ homepage: http://github.com/jamescook/RubyRedditAPI
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options: []
87
+
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ segments:
104
+ - 1
105
+ - 3
106
+ - 6
107
+ version: 1.3.6
108
+ requirements: []
109
+
110
+ rubyforge_project:
111
+ rubygems_version: 1.3.7
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: Wrapper for reddit API
115
+ test_files:
116
+ - features/reddit.yml
117
+ - features/submission.feature
118
+ - features/comment.feature
119
+ - features/user.feature
120
+ - features/base.feature
121
+ - features/message.feature
122
+ - features/api.feature
123
+ - features/step_definitions/message_steps.rb
124
+ - features/step_definitions/submission_steps.rb
125
+ - features/step_definitions/api_steps.rb
126
+ - features/step_definitions/user_steps.rb
127
+ - features/step_definitions/comment_steps.rb
128
+ - features/step_definitions/base_steps.rb
129
+ - features/support/base_helpers.rb