ruby-hackernews 1.3.6 → 1.3.7
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.
- checksums.yaml +5 -13
- data/README.rdoc +2 -0
- data/lib/ruby-hackernews/services/comment_service.rb +1 -4
- data/lib/ruby-hackernews/services/parsers/comments_info_parser.rb +18 -9
- data/lib/ruby-hackernews/services/parsers/entry_parser.rb +4 -4
- data/lib/ruby-hackernews/services/parsers/time_info_parser.rb +17 -7
- data/lib/ruby-hackernews/services/parsers/user_info_parser.rb +18 -8
- data/lib/ruby-hackernews/version.rb +1 -1
- data/spec/HNAPI/services/entries/entry_service_spec.rb +22 -24
- data/spec/HNAPI/services/entries/parsers/parser_helper.rb +5 -5
- data/spec/HNAPI/services/entries/parsers/time_info_parser_spec.rb +2 -2
- data/spec/HNAPI/services/mechanize_context_spec.rb +0 -19
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
Njg3MWZhYjFlODNkY2VlNDZiY2U2NWYxZTkyYTIwOTg4MDdjZTUyYg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a75ae2b32c9d840dd595bb25dfde7ca86364fecd
|
4
|
+
data.tar.gz: 3b125a1e73964ed58d0c1f7c51c105c667f08a2c
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MzJhYjU4YTUyZjgyMWYxZGFlZDViNjMyOGYzODBkZTE0ZjM4NGNmOGVkODNk
|
11
|
-
YjI5ZjU2MDJlYjM4YTQzZDhmN2YyMzIyMjdmNGRmNTVlMGFmOTQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
N2RmNmNlNjIwYjNjOTg1MmJlNzE4Y2I4MWUwNWFkZjBiNjQzOTYyODQ5ZTYx
|
14
|
-
MjYwYzQ0ZDUxYTZjNGExYjM3YmUyZDE4NGZkYTczNWFiNzFiY2VlZmE4MDdl
|
15
|
-
NWE2NDZiY2Q3ZGNmYzJhYzI1YTVlZTYwOTgyNDg1NmMwZjE5Nzc=
|
6
|
+
metadata.gz: e014746411f77467c3f4bd70a82acfab27d93b5e5713c5552029ed3f9df85db1dac81f8a97cb6189501d0ec1053a7b6033bbee2586a59fcf36805003f61fba7d
|
7
|
+
data.tar.gz: 8132a51491bf5b966810d5cf7ec00a203f2c54dece9d5dd9b3209ea89426bd6637ab81fe405671e57fe7b4cc8e409707bde1609848fef75801fc21ede64f268d
|
data/README.rdoc
CHANGED
@@ -172,3 +172,5 @@ Will return the HN comment url of the last submitted story of that user
|
|
172
172
|
- Daniel Da Cunha ( http://github.com/ddacunha ) for a fix on Entry#comments_count
|
173
173
|
- Nathan Campos ( http://github.com/nathanpc) for adding #text to Entry
|
174
174
|
- Girish Sonawane ( https://github.com/girishso) for adding Entry#shows and Entry#new_shows methods
|
175
|
+
- Niels Van Aken ( https://github.com/nvaken ) for a bugfix in EntryPageParser
|
176
|
+
- Pedro Lambert ( https://github.com/p-lambert ) for fixing bugs and improving structure of CommentInfoParser, TimeInfoParser and UserInfoParser
|
@@ -65,10 +65,7 @@ module RubyHackernews
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def parse_comment(element)
|
68
|
-
text_html = ""
|
69
|
-
element.search("span.comment").first.children.each do |ch|
|
70
|
-
text_html = ch.inner_html
|
71
|
-
end
|
68
|
+
text_html = element.search("span.comment").first.search("font").children.map { |x| x.inner_text }.join("\n")
|
72
69
|
header = element.search("span.comhead").first
|
73
70
|
voting = VotingInfoParser.new(element.search("td/center/a"), header).parse
|
74
71
|
user_info = UserInfoParser.new(header).parse
|
@@ -2,18 +2,27 @@ module RubyHackernews
|
|
2
2
|
|
3
3
|
class CommentsInfoParser
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(second_line)
|
6
|
+
@second_line = second_line
|
7
7
|
end
|
8
8
|
|
9
9
|
def parse
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
return unless comments_link
|
11
|
+
|
12
|
+
comments = comments_link.text.split[0].to_i
|
13
|
+
comments_page = comments_link['href']
|
14
|
+
|
15
|
+
CommentsInfo.new(comments, comments_page)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def comments_link
|
21
|
+
links.find { |link| link.text =~ /comment|discuss/ }
|
22
|
+
end
|
23
|
+
|
24
|
+
def links
|
25
|
+
@second_line.css('a')
|
17
26
|
end
|
18
27
|
|
19
28
|
end
|
@@ -20,12 +20,12 @@ module RubyHackernews
|
|
20
20
|
number = number_segment.inner_html.sub(".","").to_i if number_segment
|
21
21
|
link = LinkInfoParser.new(link_segment).parse
|
22
22
|
voting = VotingInfoParser.new(@first_line.search("td/center/a"), @second_line.search("[@class='subtext']")[0]).parse
|
23
|
-
user = UserInfoParser.new(@second_line
|
24
|
-
comments = CommentsInfoParser.new(@second_line
|
25
|
-
time = TimeInfoParser.new(@second_line
|
23
|
+
user = UserInfoParser.new(@second_line).parse
|
24
|
+
comments = CommentsInfoParser.new(@second_line).parse
|
25
|
+
time = TimeInfoParser.new(@second_line).parse
|
26
26
|
return Entry.new(number, link, voting, user, comments, time)
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
end
|
30
30
|
|
31
31
|
end
|
@@ -2,18 +2,28 @@ module RubyHackernews
|
|
2
2
|
|
3
3
|
class TimeInfoParser
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(second_line)
|
6
|
+
@second_line = second_line
|
7
7
|
end
|
8
8
|
|
9
9
|
def parse
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
return unless time_link
|
11
|
+
|
12
|
+
value = time_link.text.strip.split[0].to_i
|
13
|
+
unit_of_measure = time_link.text.strip.split[1]
|
14
|
+
|
15
|
+
TimeInfo.new(value, unit_of_measure)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def time_link
|
21
|
+
links.find { |link| link.text =~ /\sago/ }
|
15
22
|
end
|
16
23
|
|
24
|
+
def links
|
25
|
+
@second_line.css('a')
|
26
|
+
end
|
17
27
|
end
|
18
28
|
|
19
29
|
end
|
@@ -2,17 +2,27 @@ module RubyHackernews
|
|
2
2
|
|
3
3
|
class UserInfoParser
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(second_line)
|
6
|
+
@second_line = second_line
|
7
7
|
end
|
8
8
|
|
9
9
|
def parse
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
return unless user_link
|
11
|
+
|
12
|
+
user_name = user_link.inner_html
|
13
|
+
user_page = user_link['href']
|
14
|
+
|
15
|
+
UserInfo.new(user_name, user_page)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def user_link
|
21
|
+
links.find { |link| link['href'] =~ /user\?id=/ }
|
22
|
+
end
|
23
|
+
|
24
|
+
def links
|
25
|
+
@second_line.css('a')
|
16
26
|
end
|
17
27
|
|
18
28
|
end
|
@@ -7,41 +7,39 @@ module RubyHackernews
|
|
7
7
|
describe :get_entries do
|
8
8
|
|
9
9
|
it "should always call EntryPageParser with current agent" do
|
10
|
-
parser =
|
11
|
-
parser.
|
12
|
-
|
13
|
-
agent
|
14
|
-
|
15
|
-
MechanizeContext.create(:default, agent)
|
10
|
+
parser = Object.new
|
11
|
+
allow(parser).to receive_messages(:get_lines => [], :get_next_url => nil)
|
12
|
+
agent = Object.new
|
13
|
+
allow(agent).to receive_messages(:get => :page)
|
14
|
+
MechanizeContext.send(:class_variable_set, :@@contexts, {:default => agent})
|
16
15
|
service = EntryService.new
|
17
|
-
EntryPageParser.
|
16
|
+
expect(EntryPageParser).to receive(:new).at_least(1).with(:page).and_return(parser)
|
18
17
|
service.get_entries
|
19
18
|
end
|
20
19
|
|
21
20
|
it "should always call get_lines 'pages' number of times" do
|
22
21
|
pages = 5
|
23
|
-
parser =
|
24
|
-
parser.
|
25
|
-
parser.
|
26
|
-
agent =
|
27
|
-
agent.
|
28
|
-
MechanizeContext.
|
22
|
+
parser = Object.new
|
23
|
+
expect(parser).to receive(:get_lines).and_return([])
|
24
|
+
allow(parser).to receive(:get_next_url).and_return(nil)
|
25
|
+
agent = Object.new
|
26
|
+
allow(agent).to receive_messages(:get => :page)
|
27
|
+
MechanizeContext.send(:class_variable_set, :@@contexts, {:default => agent})
|
29
28
|
service = EntryService.new
|
30
|
-
EntryPageParser.
|
31
|
-
service.get_entries
|
29
|
+
allow(EntryPageParser).to receive(:new).with(:page).and_return(parser)
|
30
|
+
service.get_entries
|
32
31
|
end
|
33
32
|
|
34
33
|
it "should always call get_next_url 'pages' number of times" do
|
35
|
-
|
36
|
-
parser
|
37
|
-
parser.
|
38
|
-
|
39
|
-
agent
|
40
|
-
|
41
|
-
MechanizeContext.create(:default, agent)
|
34
|
+
parser = Object.new
|
35
|
+
allow(parser).to receive(:get_lines).and_return([])
|
36
|
+
expect(parser).to receive(:get_next_url).and_return(nil)
|
37
|
+
agent = Object.new
|
38
|
+
allow(agent).to receive_messages(:get => :page)
|
39
|
+
MechanizeContext.send(:class_variable_set, :@@contexts, {:default => agent})
|
42
40
|
service = EntryService.new
|
43
|
-
EntryPageParser.
|
44
|
-
service.get_entries
|
41
|
+
allow(EntryPageParser).to receive(:new).with(:page).and_return(parser)
|
42
|
+
service.get_entries
|
45
43
|
end
|
46
44
|
|
47
45
|
end
|
@@ -21,14 +21,14 @@ class ParserHelper
|
|
21
21
|
return Nokogiri::HTML.fragment('<a id=up_1645686 href="vote?for=1645686&dir=up&whence=%6e%65%77%73"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><a id=down_1645686 href="vote?for=1645686&dir=up&whence=%6e%65%77%73"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a>'
|
22
22
|
).children
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
#username : johnthedebs
|
26
26
|
#user page : user?id=johnthedebs
|
27
27
|
#score : 17
|
28
28
|
#comments : 2
|
29
29
|
#comment_page : item?id=1645686
|
30
30
|
def self.second_line
|
31
|
-
return Nokogiri::HTML.fragment('<td class="subtext"><span id=score_1645686>17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> 4 hours ago
|
31
|
+
return Nokogiri::HTML.fragment('<td class="subtext"><span class="score" id="score_1645686">17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> <a href="item?id=1645686">4 hours ago</a> | <a href="item?id=1645686">2 comments</a></td>')
|
32
32
|
end
|
33
33
|
|
34
34
|
#username : johnthedebs
|
@@ -36,7 +36,7 @@ class ParserHelper
|
|
36
36
|
#score : 17
|
37
37
|
#comment_page : item?id=1645686
|
38
38
|
def self.second_line_no_comments_yet
|
39
|
-
return Nokogiri::HTML.fragment('<td class="subtext"><span id=score_1645686>17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> 4 hours ago
|
39
|
+
return Nokogiri::HTML.fragment('<td colspan="2"></td><td class="subtext"><span class="score" id="score_1645686">17 points</span> by <a href="user?id=johnthedebs">johnthedebs</a> <a href="item?id=1645686">4 hours ago</a> | <a href="item?id=1645686">discuss</a></td>')
|
40
40
|
end
|
41
41
|
|
42
42
|
#username : johnthedebs
|
@@ -64,14 +64,14 @@ class ParserHelper
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def self.second_line_full
|
67
|
-
|
67
|
+
Nokogiri::HTML.fragment('<tr><td colspan=2></td><td class="subtext"><span class="score" id="score_1645745">59 points</span> by <a href="user?id=dhotson">dhotson</a> <a href="item?id=1645745">4 hours ago</a> | <a href="item?id=1645745">5 comments</a></td></tr>')
|
68
68
|
end
|
69
69
|
|
70
70
|
def self.full_page
|
71
71
|
File.open(File.join(File.dirname(__FILE__), 'hn_test_page.html'), 'r') do |file|
|
72
72
|
return Nokogiri::HTML(file)
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
end
|
76
76
|
|
77
77
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require File.join(File.dirname(__FILE__), 'parser_helper')
|
2
3
|
|
3
4
|
module RubyHackernews
|
4
5
|
describe TimeInfoParser do
|
5
6
|
|
6
7
|
before :each do
|
7
|
-
@parser = TimeInfoParser.new(
|
8
|
+
@parser = TimeInfoParser.new(ParserHelper.second_line)
|
8
9
|
end
|
9
10
|
|
10
11
|
describe :parse do
|
@@ -22,4 +23,3 @@ module RubyHackernews
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
25
|
-
|
@@ -8,25 +8,6 @@ module RubyHackernews
|
|
8
8
|
MechanizeContext.send(:class_variable_set, :@@default, nil)
|
9
9
|
end
|
10
10
|
|
11
|
-
describe "create" do
|
12
|
-
|
13
|
-
it "should instantiate class variable on use" do
|
14
|
-
MechanizeContext.create()
|
15
|
-
MechanizeContext.send(:class_variable_get, :@@contexts).should_not be_nil
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should assign new agent to hash[key]" do
|
19
|
-
MechanizeContext.create(:test_key)
|
20
|
-
MechanizeContext.send(:class_variable_get, :@@contexts)[:test_key].should be_kind_of Mechanize
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should assign new agent to default if no key passed" do
|
24
|
-
MechanizeContext.create
|
25
|
-
MechanizeContext.send(:class_variable_get, :@@contexts)[:default].should be_kind_of Mechanize
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
11
|
describe "agent=" do
|
31
12
|
|
32
13
|
it "should set @@default as passed key" do
|
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-hackernews
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Dallera
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: require_all
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 1.1.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 1.1.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: mechanize
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.0.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.0.0
|
69
69
|
description: An interface to Hacker News
|
@@ -73,7 +73,7 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
- .gitignore
|
76
|
+
- ".gitignore"
|
77
77
|
- Gemfile
|
78
78
|
- README.rdoc
|
79
79
|
- Rakefile
|
@@ -129,17 +129,17 @@ require_paths:
|
|
129
129
|
- lib
|
130
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|
131
131
|
requirements:
|
132
|
-
- -
|
132
|
+
- - ">="
|
133
133
|
- !ruby/object:Gem::Version
|
134
134
|
version: '0'
|
135
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- -
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
140
|
requirements: []
|
141
141
|
rubyforge_project:
|
142
|
-
rubygems_version: 2.
|
142
|
+
rubygems_version: 2.0.0
|
143
143
|
signing_key:
|
144
144
|
specification_version: 4
|
145
145
|
summary: An interface to Hacker News
|