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 CHANGED
@@ -1,6 +1,6 @@
1
- Ruby Reddit Client v0.1.9
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
- - Parse submissions
16
- - Comments parsing
17
- - Vote on submission
15
+ - Browse submissions
16
+ - Read comments
17
+ - Friend/unfriend redditors
18
+ - Comment & submission voting
18
19
 
19
20
 
20
21
  Running Tests:
@@ -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
@@ -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
- class Comment < Api
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
- def id
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
- def hide # soft delete?
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
- def upvote
64
- Vote.new(self).up
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 < Base
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
- def id
16
- "#{kind}_#{@id}"
17
- end
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
- def upvote
29
- Reddit::Vote.new(self).up
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
@@ -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
@@ -1,3 +1,6 @@
1
+ # @author James Cook
1
2
  module Reddit
3
+ # Capture the code version from the VERSION file
4
+ # @return [String]
2
5
  VERSION = File.exist?("VERSION") ? File.read("VERSION").chomp : ""
3
6
  end
@@ -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
- - 1
8
- - 9
9
- version: 0.1.9
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-05 00:00:00 -04:00
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: true
82
+ has_rdoc: false
82
83
  homepage: http://github.com/jamescook/RubyRedditAPI
83
84
  licenses: []
84
85