ruby_reddit_api 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +6 -5
- data/lib/ruby_reddit_api/api.rb +12 -0
- data/lib/ruby_reddit_api/base.rb +22 -0
- data/lib/ruby_reddit_api/comment.rb +17 -18
- data/lib/ruby_reddit_api/json_listing.rb +8 -0
- data/lib/ruby_reddit_api/message.rb +8 -0
- data/lib/ruby_reddit_api/submission.rb +16 -34
- data/lib/ruby_reddit_api/thing.rb +49 -0
- data/lib/ruby_reddit_api/user.rb +9 -14
- data/lib/ruby_reddit_api/version.rb +3 -0
- data/lib/ruby_reddit_api/vote.rb +6 -0
- metadata +6 -5
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
Ruby Reddit Client v0.
|
1
|
+
Ruby Reddit Client v0.2.0
|
2
2
|
==================
|
3
|
-
Tested with 1.9.2
|
3
|
+
Tested with ruby 1.9.2
|
4
4
|
|
5
5
|
Usage:
|
6
6
|
=======
|
@@ -12,9 +12,10 @@ Usage:
|
|
12
12
|
Features:
|
13
13
|
========
|
14
14
|
- Authentication
|
15
|
-
-
|
16
|
-
-
|
17
|
-
-
|
15
|
+
- Browse submissions
|
16
|
+
- Read comments
|
17
|
+
- Friend/unfriend redditors
|
18
|
+
- Comment & submission voting
|
18
19
|
|
19
20
|
|
20
21
|
Running Tests:
|
data/lib/ruby_reddit_api/api.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Reddit
|
2
2
|
|
3
|
+
# @author James Cook
|
3
4
|
class Api < Base
|
4
5
|
attr_reader :last_action, :debug
|
5
6
|
|
@@ -13,6 +14,9 @@ module Reddit
|
|
13
14
|
"<Reddit::Api user='#{user}'>"
|
14
15
|
end
|
15
16
|
|
17
|
+
# Browse submissions by subreddit
|
18
|
+
# @param [String] Subreddit to browse
|
19
|
+
# @return [Array<Reddit::Submission>]
|
16
20
|
def browse(subreddit, options={})
|
17
21
|
subreddit = sanitize_subreddit(subreddit)
|
18
22
|
options.merge! :handler => "Submission"
|
@@ -22,18 +26,26 @@ module Reddit
|
|
22
26
|
read("/r/#{subreddit}.json", options )
|
23
27
|
end
|
24
28
|
|
29
|
+
# Read sent messages
|
30
|
+
# @return [Array<Reddit::Message>]
|
25
31
|
def sent_messages
|
26
32
|
messages :sent
|
27
33
|
end
|
28
34
|
|
35
|
+
# Read received messages
|
36
|
+
# @return [Array<Reddit::Message>]
|
29
37
|
def received_messages
|
30
38
|
messages :inbox
|
31
39
|
end
|
32
40
|
|
41
|
+
# Read received comments
|
42
|
+
# @return [Array<Reddit::Message>]
|
33
43
|
def comments
|
34
44
|
messages :comments
|
35
45
|
end
|
36
46
|
|
47
|
+
# Read post replies
|
48
|
+
# @return [Array<Reddit::Message>]
|
37
49
|
def post_replies
|
38
50
|
messages :selfreply
|
39
51
|
end
|
data/lib/ruby_reddit_api/base.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Reddit
|
2
|
+
# Base module all other classes descend from. Stores the cookie, modhash and user info for many API calls. Handles authentication and directs JSON
|
3
|
+
# to the relevant handler.
|
4
|
+
# @author James Cook
|
2
5
|
class Base
|
3
6
|
include HTTParty
|
4
7
|
|
@@ -10,47 +13,66 @@ module Reddit
|
|
10
13
|
@debug = StringIO.new
|
11
14
|
end
|
12
15
|
|
16
|
+
# @return [String]
|
13
17
|
def inspect
|
14
18
|
"<Reddit::Base user='#{user}'>"
|
15
19
|
end
|
16
20
|
|
21
|
+
# Login to Reddit and capture the cookie
|
22
|
+
# @return [Boolean] Login success or failure
|
17
23
|
def login
|
18
24
|
capture_session(self.class.post( "/api/login", {:body => {:user => @user, :passwd => @password}, :debug_output => @debug} ) )
|
19
25
|
logged_in?
|
20
26
|
end
|
21
27
|
|
28
|
+
# Remove the cookie to effectively logout of Reddit
|
29
|
+
# @return [nil]
|
22
30
|
def logout
|
23
31
|
Reddit::Base.instance_variable_set("@cookie",nil)
|
24
32
|
end
|
25
33
|
|
34
|
+
# @return [String, nil]
|
26
35
|
def cookie
|
27
36
|
Reddit::Base.cookie
|
28
37
|
end
|
29
38
|
|
39
|
+
# A kind of authenticity token for many API calls
|
40
|
+
# @return [String, nil]
|
30
41
|
def modhash
|
31
42
|
Reddit::Base.modhash
|
32
43
|
end
|
33
44
|
|
45
|
+
# Reddit's displayed ID for the logged in user
|
46
|
+
# @return [String]
|
34
47
|
def user_id
|
35
48
|
Reddit::Base.user_id
|
36
49
|
end
|
37
50
|
|
51
|
+
# Logged in user
|
52
|
+
# @return [String]
|
38
53
|
def user
|
39
54
|
Reddit::Base.user
|
40
55
|
end
|
41
56
|
|
57
|
+
# The session is authenticated if the captured cookie shows a valid session is in place
|
58
|
+
# @return [true,false]
|
42
59
|
def logged_in?
|
43
60
|
!!(cookie && (cookie =~ /reddit_session/) != nil)
|
44
61
|
end
|
45
62
|
|
63
|
+
# @return String
|
46
64
|
def user_agent
|
47
65
|
self.class.user_agent
|
48
66
|
end
|
49
67
|
|
68
|
+
# HTTP headers to be sent in all API requests. At a minimum, 'User-agent' and 'Cookie' are needed.
|
69
|
+
# @return Hash
|
50
70
|
def base_headers
|
51
71
|
self.class.base_headers
|
52
72
|
end
|
53
73
|
|
74
|
+
# Base communication function for nearly all API calls
|
75
|
+
# @return [Reddit::Submission, Reddit::Comment, Reddit::User, false] Various reddit-related, json parseable objects
|
54
76
|
def read(url, options={})
|
55
77
|
unless throttled?
|
56
78
|
@debug.rewind
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Reddit
|
2
|
-
|
2
|
+
# @author James Cook
|
3
|
+
class Comment < Thing
|
4
|
+
|
3
5
|
include JsonListing
|
4
6
|
attr_reader :body, :subreddit_id, :name, :created, :downs, :author, :created_utc, :body_html, :link_id, :parent_id, :likes, :replies, :subreddit, :ups, :debug, :kind
|
5
7
|
def initialize(json)
|
@@ -11,33 +13,34 @@ module Reddit
|
|
11
13
|
"<Reddit::Comment author='#{@author}' body='#{short_body}'>"
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
"#{kind}_#{@id}"
|
16
|
-
end
|
17
|
-
|
18
|
-
def author
|
19
|
-
@author_data ||= read("/user/#{@author}/about.json", :handler => "User")
|
20
|
-
end
|
21
|
-
|
16
|
+
# @return [String]
|
22
17
|
def to_s
|
23
18
|
body
|
24
19
|
end
|
25
20
|
|
21
|
+
# Modify a comment
|
22
|
+
# @return [true,false]
|
26
23
|
def edit(newtext)
|
27
24
|
resp=self.class.post("/api/editusertext", {:body => {:thing_id => id, :uh => modhash, :r => subreddit, :text => newtext }, :headers => base_headers, :debug_output => @debug })
|
28
25
|
resp.code == 200
|
29
26
|
end
|
30
27
|
|
31
|
-
|
28
|
+
# Hide a comment
|
29
|
+
# @return [true,false]
|
30
|
+
def hide
|
32
31
|
resp=self.class.post("/api/del", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => "removed" }, :headers => base_headers, :debug_output => @debug })
|
33
32
|
resp.code == 200
|
34
33
|
end
|
35
34
|
|
35
|
+
# Remove a comment
|
36
|
+
# @return [true,false]
|
36
37
|
def remove
|
37
38
|
resp=self.class.post("/api/remove", {:body => {:id => id, :uh => modhash, :r => subreddit}, :headers => base_headers, :debug_output => @debug })
|
38
39
|
resp.code == 200
|
39
40
|
end
|
40
41
|
|
42
|
+
# Approve a comment
|
43
|
+
# @return [true,false]
|
41
44
|
def approve
|
42
45
|
resp=self.class.post("/api/approve", {:body => {:id => id, :uh => modhash, :r => subreddit}, :headers => base_headers, :debug_output => @debug })
|
43
46
|
resp.code == 200
|
@@ -55,19 +58,15 @@ module Reddit
|
|
55
58
|
add_distinction "no"
|
56
59
|
end
|
57
60
|
|
61
|
+
# Reply to another comment
|
62
|
+
# @return [true,false]
|
58
63
|
def reply(text)
|
59
64
|
resp = self.class.post("/api/comment", {:body => {:thing_id => id, :text => text, :uh => modhash, :r => subreddit }, :headers => base_headers, :debug_output => @debug })
|
60
65
|
resp.code == 200
|
61
66
|
end
|
62
67
|
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
def downvote
|
68
|
-
Vote.new(self).down
|
69
|
-
end
|
70
|
-
|
68
|
+
# Trimmed comment body suitable for #inspect
|
69
|
+
# @return [String]
|
71
70
|
def short_body
|
72
71
|
str = body.to_s
|
73
72
|
if str.size > 15
|
@@ -1,3 +1,4 @@
|
|
1
|
+
#@author James Cook
|
1
2
|
module Reddit
|
2
3
|
module JsonListing
|
3
4
|
def self.included(base)
|
@@ -6,6 +7,9 @@ module Reddit
|
|
6
7
|
end
|
7
8
|
|
8
9
|
module ClassMethods
|
10
|
+
|
11
|
+
# @param [Hash] JSON received from Reddit
|
12
|
+
# @return [Array<Reddit::Submission, Reddit::User, Reddit::Comment, Reddit::Message>]
|
9
13
|
def parse(json)
|
10
14
|
results = []
|
11
15
|
if json.is_a?(Array)
|
@@ -28,10 +32,14 @@ module Reddit
|
|
28
32
|
end
|
29
33
|
end
|
30
34
|
module InstanceMethods
|
35
|
+
# Iterate over JSON and set instance variables that map to each JSON key
|
36
|
+
# @param [Hash] JSON received from Reddit
|
37
|
+
# @return [true]
|
31
38
|
def parse(json)
|
32
39
|
json.keys.each do |key|
|
33
40
|
instance_variable_set("@#{key}", json[key])
|
34
41
|
end
|
42
|
+
true
|
35
43
|
end
|
36
44
|
end
|
37
45
|
end
|
@@ -1,16 +1,22 @@
|
|
1
|
+
# @author James Cook
|
1
2
|
module Reddit
|
2
3
|
class Message < Base
|
3
4
|
include JsonListing
|
5
|
+
|
4
6
|
attr_reader :body, :was_comment, :kind, :first_message, :name, :created, :dest, :created_utc, :body_html, :subreddit, :parent_id, :context, :replies, :subject, :debug
|
5
7
|
def initialize(json)
|
6
8
|
parse(json)
|
7
9
|
@debug = StringIO.new
|
8
10
|
end
|
9
11
|
|
12
|
+
# The reddit ID of this message
|
13
|
+
# @return [String]
|
10
14
|
def id
|
11
15
|
"#{kind}_#{@id}"
|
12
16
|
end
|
13
17
|
|
18
|
+
# The author of the message. The data is lazy-loaded and cached on the message
|
19
|
+
# @return [Reddit::User]
|
14
20
|
def author
|
15
21
|
@author_data ||= read("/user/#{@author}/about.json", :handler => "User")
|
16
22
|
end
|
@@ -19,6 +25,8 @@ module Reddit
|
|
19
25
|
"<Reddit::Message '#{short_body}'>"
|
20
26
|
end
|
21
27
|
|
28
|
+
# Trimmed comment body suitable for #inspect
|
29
|
+
# @return [String]
|
22
30
|
def short_body
|
23
31
|
if body.size > 15
|
24
32
|
body[0..15]
|
@@ -1,58 +1,45 @@
|
|
1
|
+
# @author James Cook
|
1
2
|
module Reddit
|
2
|
-
class Submission <
|
3
|
+
class Submission < Thing
|
3
4
|
include JsonListing
|
4
5
|
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
|
|
6
|
-
def initialize(data)
|
7
|
-
parse(data)
|
8
|
-
@debug = StringIO.new
|
9
|
-
end
|
10
|
-
|
11
7
|
def inspect
|
12
8
|
"<Reddit::Submission id='#{id}' author='#{@author}' title='#{title}'>"
|
13
9
|
end
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def author
|
20
|
-
@author_data ||= read("/user/#{@author}/about.json", :handler => "User")
|
21
|
-
end
|
22
|
-
|
11
|
+
# Add a comment to a submission
|
12
|
+
# @param [String] Comment text
|
13
|
+
# @return [true,false]
|
23
14
|
def add_comment(text)
|
24
15
|
resp = self.class.post("/api/comment", {:body => {:thing_id => id, :text => text, :uh => modhash, :r => subreddit }, :headers => base_headers, :debug_output => @debug })
|
25
16
|
resp.code == 200
|
26
17
|
end
|
27
18
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def downvote
|
33
|
-
Reddit::Vote.new(self).down
|
34
|
-
end
|
35
|
-
|
19
|
+
# Save submission
|
20
|
+
# @return [true,false]
|
36
21
|
def save
|
37
22
|
toggle :save
|
38
23
|
end
|
39
24
|
|
25
|
+
# Unsave submission
|
26
|
+
# @return [true,false]
|
40
27
|
def unsave
|
41
28
|
toggle :unsave
|
42
29
|
end
|
43
30
|
|
31
|
+
# Hide submission
|
32
|
+
# @return [true,false]
|
44
33
|
def hide
|
45
34
|
toggle :hide
|
46
35
|
end
|
47
36
|
|
37
|
+
# Unhide submission
|
38
|
+
# @return [true,false]
|
48
39
|
def unhide
|
49
40
|
toggle :unhide
|
50
41
|
end
|
51
42
|
|
52
|
-
def report
|
53
|
-
toggle :report
|
54
|
-
end
|
55
|
-
|
56
43
|
def moderator_distinguish
|
57
44
|
add_distinction "yes"
|
58
45
|
end
|
@@ -65,6 +52,9 @@ module Reddit
|
|
65
52
|
add_distinction "no"
|
66
53
|
end
|
67
54
|
|
55
|
+
# Fetch submission comments
|
56
|
+
# @todo Move to 'Thing' class
|
57
|
+
# @return [Array<Reddit::Comment>]
|
68
58
|
def comments(more=false)
|
69
59
|
#TODO Get morechildren to work correctly
|
70
60
|
if more && last_comment_id
|
@@ -87,13 +77,5 @@ module Reddit
|
|
87
77
|
resp=self.class.post("/api/distinguish/#{verb}", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => "distinguishing..."}, :headers => base_headers, :debug_output => @debug })
|
88
78
|
resp.code == 200
|
89
79
|
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
80
|
end
|
99
81
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Reddit
|
2
|
+
# @author James Cook
|
3
|
+
class Thing < Base
|
4
|
+
include JsonListing
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
parse(data)
|
8
|
+
@debug = StringIO.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# The reddit ID of this entity
|
12
|
+
# @return [String]
|
13
|
+
def id
|
14
|
+
"#{kind}_#{@id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# The author of the entity. The data is lazy-loaded and cached on the object
|
18
|
+
# @return [Reddit::User]
|
19
|
+
def author
|
20
|
+
@author_data ||= read("/user/#{@author}/about.json", :handler => "User")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Upvote thing
|
24
|
+
# @return [true,false]
|
25
|
+
def upvote
|
26
|
+
Reddit::Vote.new(self).up
|
27
|
+
end
|
28
|
+
|
29
|
+
# Downvote thing
|
30
|
+
# @return [true,false]
|
31
|
+
def downvote
|
32
|
+
Reddit::Vote.new(self).down
|
33
|
+
end
|
34
|
+
|
35
|
+
# Report thing
|
36
|
+
# @return [true,false]
|
37
|
+
def report
|
38
|
+
toggle :report
|
39
|
+
end
|
40
|
+
|
41
|
+
def toggle(which)
|
42
|
+
return false unless logged_in?
|
43
|
+
mapping = {:save => "save", :unsave => "unsave", :hide => "hidden", :unhide => "unhidden", :report => "report"}
|
44
|
+
mode = mapping[which]
|
45
|
+
resp = self.class.post("/api/#{which}", {:body => {:id => id, :uh => modhash, :r => subreddit, :executed => mode }, :headers => base_headers, :debug_output => @debug })
|
46
|
+
resp.code == 200
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/ruby_reddit_api/user.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
1
|
module Reddit
|
2
|
+
# @author James Cook
|
3
3
|
class User < Api
|
4
|
+
include JSONListing
|
4
5
|
attr_reader :name, :debug, :created, :created_utc, :link_karma, :comment_karma, :is_mod, :has_mod_mail, :kind
|
5
6
|
def initialize(json)
|
6
7
|
@debug = StringIO.new
|
@@ -11,37 +12,31 @@ module Reddit
|
|
11
12
|
"<Reddit::User name='#{name}'>"
|
12
13
|
end
|
13
14
|
|
15
|
+
# The reddit ID of this submission
|
16
|
+
# @return [String]
|
14
17
|
def id
|
15
18
|
"#{kind}_#{@id}"
|
16
19
|
end
|
17
20
|
|
21
|
+
# @return [String]
|
18
22
|
def to_s
|
19
23
|
name
|
20
24
|
end
|
21
25
|
|
26
|
+
# Add redditor as friend. Requires a authenticated user.
|
27
|
+
# @return [true,false]
|
22
28
|
def friend
|
23
29
|
capture_user_id
|
24
30
|
resp=self.class.post("/api/friend", {:body => {:name => name, :container => user_id, :type => "friend", :uh => modhash}, :headers => base_headers, :debug_output => @debug })
|
25
31
|
resp.code == 200
|
26
32
|
end
|
27
33
|
|
34
|
+
# Remove redditor as friend. Requires a authenticated user.
|
35
|
+
# @return [true,false]
|
28
36
|
def unfriend
|
29
37
|
capture_user_id
|
30
38
|
resp=self.class.post("/api/unfriend", {:body => {:name => name, :container => user_id, :type => "friend", :uh => modhash}, :headers => base_headers, :debug_output => @debug })
|
31
39
|
resp.code == 200
|
32
40
|
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
41
|
end
|
47
42
|
end
|
data/lib/ruby_reddit_api/vote.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# @author James Cook
|
1
2
|
module Reddit
|
2
3
|
class Vote < Base
|
3
4
|
attr_reader :submission
|
@@ -6,14 +7,19 @@ module Reddit
|
|
6
7
|
@submission = submission
|
7
8
|
end
|
8
9
|
|
10
|
+
# Upvote submission or comment
|
11
|
+
# @return [true,false]
|
9
12
|
def up
|
10
13
|
vote(:up)
|
11
14
|
end
|
12
15
|
|
16
|
+
# Downvote submission or comment
|
17
|
+
# @return [true,false]
|
13
18
|
def down
|
14
19
|
vote(:down)
|
15
20
|
end
|
16
21
|
|
22
|
+
#@return [String]
|
17
23
|
def inspect
|
18
24
|
"<Reddit::Vote>"
|
19
25
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- James Cook
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-06 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -54,6 +54,7 @@ extra_rdoc_files: []
|
|
54
54
|
|
55
55
|
files:
|
56
56
|
- lib/ruby_reddit_api.rb
|
57
|
+
- lib/ruby_reddit_api/thing.rb
|
57
58
|
- lib/ruby_reddit_api/user.rb
|
58
59
|
- lib/ruby_reddit_api/comment.rb
|
59
60
|
- lib/ruby_reddit_api/message.rb
|
@@ -78,7 +79,7 @@ files:
|
|
78
79
|
- features/step_definitions/comment_steps.rb
|
79
80
|
- features/step_definitions/base_steps.rb
|
80
81
|
- features/support/base_helpers.rb
|
81
|
-
has_rdoc:
|
82
|
+
has_rdoc: false
|
82
83
|
homepage: http://github.com/jamescook/RubyRedditAPI
|
83
84
|
licenses: []
|
84
85
|
|