hackernews 0.1.0 → 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.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.
|