ruby_reddit_api 0.1.9 → 0.2.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/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
|
|