hackernews 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -3
- data/lib/hackernews.rb +59 -20
- data/test/hackernews_test.rb +7 -1
- metadata +11 -4
data/README.rdoc
CHANGED
@@ -10,16 +10,16 @@ This is a fairly simple Ruby class for accessing certain parts of Hacker News (h
|
|
10
10
|
|
11
11
|
* Handles Hacker News session cookie and login.
|
12
12
|
* Can retreive user page, along with karma and average karma values.
|
13
|
+
* Can vote on posts and comments.
|
14
|
+
* Can comment on posts and other comments.
|
13
15
|
|
14
16
|
== To Do
|
15
17
|
|
16
|
-
* Add ability to vote.
|
17
18
|
* Add ability to post news.
|
18
|
-
* Add ability to post comments.
|
19
19
|
|
20
20
|
== Source Code
|
21
21
|
|
22
|
-
|
22
|
+
http://github.com/seven1m/hackernews
|
23
23
|
|
24
24
|
== Installation
|
25
25
|
|
@@ -32,6 +32,8 @@ This is a fairly simple Ruby class for accessing certain parts of Hacker News (h
|
|
32
32
|
hn = HackerNews.new(USERNAME, PASSWORD)
|
33
33
|
hn.karma # => '62'
|
34
34
|
hn.average_karma # => '1.87'
|
35
|
+
hn.vote(123)
|
36
|
+
hn.comment(123, 'my comment')
|
35
37
|
|
36
38
|
== Feedback
|
37
39
|
|
data/lib/hackernews.rb
CHANGED
@@ -4,34 +4,33 @@ require 'open-uri'
|
|
4
4
|
|
5
5
|
class HackerNews
|
6
6
|
|
7
|
-
VERSION = '0.
|
7
|
+
VERSION = '0.2.0'
|
8
8
|
|
9
9
|
# Returns the version string for the library.
|
10
10
|
def self.version
|
11
11
|
VERSION
|
12
12
|
end
|
13
13
|
|
14
|
-
BASE_URL
|
15
|
-
|
14
|
+
BASE_URL = "http://news.ycombinator.com"
|
15
|
+
ITEM_URL = "#{BASE_URL}/item?id=%s"
|
16
|
+
USER_URL = "#{BASE_URL}/user?id=%s"
|
17
|
+
LOGIN_SUBMIT_URL = "#{BASE_URL}/y"
|
18
|
+
COMMENT_SUBMIT_URL = "#{BASE_URL}/r"
|
19
|
+
|
20
|
+
class LoginError < RuntimeError; end
|
16
21
|
|
17
22
|
# Creates a new HackerNews object.
|
18
23
|
# Specify your username and password.
|
19
24
|
def initialize(username, password)
|
20
|
-
login_url =
|
21
|
-
form_html =
|
22
|
-
|
23
|
-
response =
|
24
|
-
req = Net::HTTP::Post.new('/y')
|
25
|
-
req.set_form_data(
|
26
|
-
'fnid' => form_html.match(/<input type=hidden name="fnid" value="([^"]+)"/)[1],
|
27
|
-
'u' => username,
|
28
|
-
'p' => password
|
29
|
-
)
|
30
|
-
http.request(req)
|
31
|
-
end
|
32
|
-
@cookie = response.header['set-cookie']
|
25
|
+
login_url = get(BASE_URL).match(/href="([^"]+)">login<\/a>/)[1]
|
26
|
+
form_html = get(BASE_URL + login_url)
|
27
|
+
fnid = form_html.match(/<input type=hidden name="fnid" value="([^"]+)"/)[1]
|
28
|
+
response = post(LOGIN_SUBMIT_URL, 'fnid' => fnid, 'u' => username, 'p' => password)
|
33
29
|
@username = username
|
34
30
|
@password = password
|
31
|
+
unless @cookie = response.header['set-cookie']
|
32
|
+
raise LoginError, "Login credentials did not work."
|
33
|
+
end
|
35
34
|
end
|
36
35
|
|
37
36
|
# Retrieves the karma for the logged in user, or for the specified username (if given).
|
@@ -49,13 +48,53 @@ class HackerNews
|
|
49
48
|
username ||= @username
|
50
49
|
@user_pages ||= {}
|
51
50
|
@user_pages[username] ||= begin
|
52
|
-
|
51
|
+
get(USER_URL % username)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Up-vote on a post or on a comment by passing in the id number.
|
56
|
+
def vote(id)
|
57
|
+
url = get(ITEM_URL % id).match(/<a id=up_\d+ onclick="return vote\(this\)" href="(vote\?[^"]+)">/)[1]
|
58
|
+
get(BASE_URL + '/' + url)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Post a comment on a posted item or on another comment.
|
62
|
+
def comment(id, text)
|
63
|
+
fnid = get(ITEM_URL % id).match(/<input type=hidden name="fnid" value="([^"]+)"/)[1]
|
64
|
+
post(COMMENT_SUBMIT_URL, 'fnid' => fnid, 'text' => text)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def url_path_and_query(url)
|
70
|
+
if url.path and url.query
|
71
|
+
"#{url.path}?#{url.query}"
|
72
|
+
elsif url.path.to_s.any?
|
73
|
+
url.path
|
74
|
+
else
|
75
|
+
'/'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def get(url)
|
80
|
+
url = URI.parse(url)
|
53
81
|
response = Net::HTTP.start(url.host, url.port) do |http|
|
54
|
-
|
55
|
-
http.get(url.path + '?' + url.query, header)
|
82
|
+
http.get(url_path_and_query(url), build_header)
|
56
83
|
end
|
57
84
|
response.body
|
58
85
|
end
|
59
|
-
|
86
|
+
|
87
|
+
def post(url, data)
|
88
|
+
url = URI.parse(url)
|
89
|
+
Net::HTTP.new(url.host, url.port).start do |http|
|
90
|
+
req = Net::HTTP::Post.new(url.path, build_header)
|
91
|
+
req.set_form_data(data)
|
92
|
+
http.request(req)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_header
|
97
|
+
@cookie && {'Cookie' => @cookie}
|
98
|
+
end
|
60
99
|
|
61
100
|
end
|
data/test/hackernews_test.rb
CHANGED
@@ -12,10 +12,16 @@ class HackerNewsTest < Test::Unit::TestCase
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def test_session_cookie
|
16
16
|
assert @hn.instance_eval('@cookie') =~ /user=[a-z0-9]+;/i
|
17
17
|
end
|
18
18
|
|
19
|
+
def test_login_failure
|
20
|
+
assert_raise HackerNews::LoginError do
|
21
|
+
HackerNews.new('foobar00000', 'baz')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
19
25
|
def test_karma
|
20
26
|
assert @hn.karma.to_s != ''
|
21
27
|
assert @hn.karma('pg').to_i > 59000
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hackernews
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Tim Morgan
|
@@ -38,18 +43,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
38
43
|
requirements:
|
39
44
|
- - ">="
|
40
45
|
- !ruby/object:Gem::Version
|
46
|
+
segments:
|
47
|
+
- 0
|
41
48
|
version: "0"
|
42
|
-
version:
|
43
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
51
|
- - ">="
|
46
52
|
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
47
55
|
version: "0"
|
48
|
-
version:
|
49
56
|
requirements: []
|
50
57
|
|
51
58
|
rubyforge_project:
|
52
|
-
rubygems_version: 1.3.
|
59
|
+
rubygems_version: 1.3.6
|
53
60
|
signing_key:
|
54
61
|
specification_version: 3
|
55
62
|
summary: Ruby gem to login and interact with the Hacker News website.
|