hacker_news 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +20 -0
- data/README +0 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/hacker_news/item.rb +24 -0
- data/lib/hacker_news/scraper.rb +25 -0
- data/lib/hacker_news.rb +5 -0
- data/test/fixtures/index.html +37 -0
- data/test/helper.rb +18 -0
- data/test/unit/test_scraper.rb +21 -0
- metadata +155 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
gem "nokogiri", "~> 1.4.0"
|
5
|
+
gem "iconv"
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
gem "fakeweb"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
fakeweb (1.3.0)
|
5
|
+
git (1.2.5)
|
6
|
+
iconv (0.1)
|
7
|
+
jeweler (1.5.2)
|
8
|
+
bundler (~> 1.0.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rake
|
11
|
+
nokogiri (1.4.4)
|
12
|
+
rake (0.8.7)
|
13
|
+
rcov (0.9.9)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
bundler (~> 1.0.0)
|
20
|
+
fakeweb
|
21
|
+
iconv
|
22
|
+
jeweler (~> 1.5.2)
|
23
|
+
nokogiri (~> 1.4.0)
|
24
|
+
rcov
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Aleksandr Lossenko
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= hacker_news
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to hacker_news
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 Aleksandr Lossenko. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "hacker_news"
|
16
|
+
gem.homepage = "http://github.com/egze/hacker_news"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Wrapper for Hacker News website}
|
19
|
+
gem.description = %Q{Fetches newest 5 pages from Hacker News and returns convenient ruby objects}
|
20
|
+
gem.email = "aleksandr.lossenko@gmail.com"
|
21
|
+
gem.authors = ["Aleksandr Lossenko"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'test'
|
39
|
+
test.pattern = 'test/**/test_*.rb'
|
40
|
+
test.verbose = true
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "hacker_news #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HackerNews
|
2
|
+
|
3
|
+
class Item
|
4
|
+
|
5
|
+
attr_accessor :id, :position, :points, :title, :url, :comments, :user, :created_at
|
6
|
+
|
7
|
+
def initialize(node, position)
|
8
|
+
tr = node.parent.parent
|
9
|
+
points_comments_tr = tr.next
|
10
|
+
points_comments_td = points_comments_tr.css("td.subtext")[0]
|
11
|
+
|
12
|
+
@title = Iconv.iconv('iso-8859-1//translit', 'utf-8', node.text)[0].to_s.strip
|
13
|
+
@url = node[:href]
|
14
|
+
@position = position
|
15
|
+
@points = points_comments_td.css("span")[0].text.to_i
|
16
|
+
@id = points_comments_td.css("span")[0][:id].split("_")[1].to_i
|
17
|
+
@user = points_comments_td.css("a")[0].text.strip
|
18
|
+
@comments = points_comments_td.css("a")[1].text.to_i
|
19
|
+
@created_at = points_comments_td.text.match(/by [-\w]+ (.*) \|/)[1].strip rescue ""
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HackerNews
|
2
|
+
|
3
|
+
class Scraper
|
4
|
+
|
5
|
+
URL = "http://news.ycombinator.com"
|
6
|
+
|
7
|
+
def self.articles(pages = 5)
|
8
|
+
|
9
|
+
pagination = ""
|
10
|
+
result = []
|
11
|
+
|
12
|
+
0.upto(pages - 1) do |page|
|
13
|
+
doc = Nokogiri::HTML(open(URL+pagination))
|
14
|
+
articles = doc.css("td.title > a:first-child")
|
15
|
+
next_page = articles.pop
|
16
|
+
pagination = next_page[:href]
|
17
|
+
articles.each_with_index {|a, i| result << Item.new(a, (page * 30) + i + 1)}
|
18
|
+
end
|
19
|
+
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/hacker_news.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
<html><head><link rel="stylesheet" type="text/css" href="http://ycombinator.com/news.css">
|
3
|
+
<link rel="shortcut icon" href="http://ycombinator.com/favicon.ico">
|
4
|
+
<script>
|
5
|
+
function byId(id) {
|
6
|
+
return document.getElementById(id);
|
7
|
+
}
|
8
|
+
|
9
|
+
function vote(node) {
|
10
|
+
var v = node.id.split(/_/); // {'up', '123'}
|
11
|
+
var item = v[1];
|
12
|
+
|
13
|
+
// adjust score
|
14
|
+
var score = byId('score_' + item);
|
15
|
+
var newscore = parseInt(score.innerHTML) + (v[0] == 'up' ? 1 : -1);
|
16
|
+
score.innerHTML = newscore + (newscore == 1 ? ' point' : ' points');
|
17
|
+
|
18
|
+
// hide arrows
|
19
|
+
byId('up_' + item).style.visibility = 'hidden';
|
20
|
+
byId('down_' + item).style.visibility = 'hidden';
|
21
|
+
|
22
|
+
// ping server
|
23
|
+
var ping = new Image();
|
24
|
+
ping.src = node.href;
|
25
|
+
|
26
|
+
return false; // cancel browser nav
|
27
|
+
} </script><title>Hacker News</title></head><body><center><table border=0 cellpadding=0 cellspacing=0 width="85%" bgcolor=#f6f6ef><tr><td bgcolor=#ff6600><table border=0 cellpadding=0 cellspacing=0 width="100%" style="padding:2px"><tr><td style="width:18px;padding-right:4px"><a href="http://ycombinator.com"><img src="http://ycombinator.com/images/y18.gif" width=18 height=18 style="border:1px #ffffff solid;"></img></a></td><td style="line-height:12pt; height:10px;"><span class="pagetop"><b><a href="news">Hacker News</a></b><img src="http://ycombinator.com/images/s.gif" height=1 width=10><a href="newest">new</a> | <a href="newcomments">comments</a> | <a href="ask">ask</a> | <a href="jobs">jobs</a> | <a href="submit">submit</a></span></td><td style="text-align:right;padding-right:4px;"><span class="pagetop"><a href="/x?fnid=epVoi4m0mi">login</a></span></td></tr></table></td></tr><tr style="height:10px"></tr><tr><td><table border=0 cellpadding=0 cellspacing=0><tr><td align=right valign=top class="title">61.</td><td><center><a id=up_2389994 href="vote?for=2389994&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2389994></span></center></td><td class="title"><a href="http://www.marco.org/4222285032">Apple’s boring hardware updates</a><span class="comhead"> (marco.org) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2389994>127 points</span> by <a href="user?id=remi">remi</a> 19 hours ago | <a href="item?id=2389994">59 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">62.</td><td><center><a id=up_2391545 href="vote?for=2391545&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2391545></span></center></td><td class="title"><a href="http://opensource.com/life/11/3/nasa-concludes-first-open-source-summit-aims-make-openness-default">NASA concludes first Open Source Summit, aims to make openness the default</a><span class="comhead"> (opensource.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2391545>16 points</span> by <a href="user?id=Tsiolkovsky">Tsiolkovsky</a> 6 hours ago | <a href="item?id=2391545">2 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">63.</td><td><center><a id=up_2390765 href="vote?for=2390765&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2390765></span></center></td><td class="title"><a href="http://codingrelic.geekhold.com/2011/03/non-blocking-programmers.html">Non-blocking Programmers</a><span class="comhead"> (geekhold.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2390765>51 points</span> by <a href="user?id=srikar">srikar</a> 12 hours ago | <a href="item?id=2390765">23 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">64.</td><td><center><a id=up_2389967 href="vote?for=2389967&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2389967></span></center></td><td class="title"><a href="http://www.physicscentral.com/buzz/blog/index.cfm?postid=6659555448783718990&1">Urban Decay: Exploring an old abandoned particle collider facility</a><span class="comhead"> (physicscentral.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2389967>117 points</span> by <a href="user?id=dstein">dstein</a> 19 hours ago | <a href="item?id=2389967">29 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">65.</td><td><center><a id=up_2393043 href="vote?for=2393043&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2393043></span></center></td><td class="title"><a href="http://www.engadget.com/2011/03/31/google-working-on-a-face-recognition-app-that-leads-to-your-pers/" rel="nofollow">Google making a face recognition app that leads to your personal info</a><span class="comhead"> (engadget.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2393043>3 points</span> by <a href="user?id=lotusleaf1987">lotusleaf1987</a> 1 hour ago | <a href="item?id=2393043">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">66.</td><td><center><a id=up_2392549 href="vote?for=2392549&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392549></span></center></td><td class="title"><a href="http://hivespun.tumblr.com/post/4199646942/hive-spun-beta-testing" rel="nofollow">HiveSpun.com Beta: Online Art Collaboration</a><span class="comhead"> (hivespun.tumblr.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392549>6 points</span> by <a href="user?id=torme">torme</a> 3 hours ago | <a href="item?id=2392549">1 comment</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">67.</td><td><center><a id=up_2392371 href="vote?for=2392371&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392371></span></center></td><td class="title"><a href="http://blog.cuphon.com/design-coffee-and-code-how-were-building-a-co">Design, Coffee, and Code: How We're Building a Company Half a World Away.</a><span class="comhead"> (cuphon.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392371>25 points</span> by <a href="user?id=gwil">gwil</a> 3 hours ago | <a href="item?id=2392371">6 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">68.</td><td><center><a id=up_2390816 href="vote?for=2390816&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2390816></span></center></td><td class="title"><a href="https://github.com/agentzh/ngx_openresty">Turning Nginx into Full-Stack Web Application Platform (By Taobao.com)</a><span class="comhead"> (github.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2390816>44 points</span> by <a href="user?id=Polat">Polat</a> 11 hours ago | <a href="item?id=2390816">8 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">69.</td><td><center><a id=up_2393005 href="vote?for=2393005&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2393005></span></center></td><td class="title"><a href="http://www.engineyard.com/blog/2011/how-long-is-your-measuring-stick/" rel="nofollow">How long is your measuring stick?</a><span class="comhead"> (engineyard.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2393005>3 points</span> by <a href="user?id=mshe">mshe</a> 1 hour ago | <a href="item?id=2393005">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">70.</td><td><center><a id=up_2393004 href="vote?for=2393004&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2393004></span></center></td><td class="title"><a href="http://www.catonmat.net/blog/follow-hacker-news-from-the-console" rel="nofollow">At work? Follow Hacker News from the Console</a><span class="comhead"> (catonmat.net) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2393004>3 points</span> by <a href="user?id=fosk">fosk</a> 1 hour ago | <a href="item?id=2393004">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">71.</td><td><center><a id=up_2392977 href="vote?for=2392977&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392977></span></center></td><td class="title"><a href="http://parkedavenue.com" rel="nofollow">Free hosted landing pages for your domains</a><span class="comhead"> (parkedavenue.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392977>3 points</span> by <a href="user?id=jeffrey999">jeffrey999</a> 1 hour ago | <a href="item?id=2392977">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">72.</td><td><center><a id=up_2388432 href="vote?for=2388432&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2388432></span></center></td><td class="title"><a href="http://googleblog.blogspot.com/2011/03/1s-right-recommendations-right-when-you.html"> +1’s: the right recommendations right when you want them—in your search results</a><span class="comhead"> (googleblog.blogspot.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2388432>205 points</span> by <a href="user?id=Anon84">Anon84</a> 1 day ago | <a href="item?id=2388432">83 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">73.</td><td><center><a id=up_2391735 href="vote?for=2391735&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2391735></span></center></td><td class="title"><a href="http://techcrunch.com/2011/03/31/what’s-the-most-difficult-ceo-skill-managing-your-own-psychology/">What’s The Most Difficult CEO Skill? (Ben Horowitz).</a><span class="comhead"> (techcrunch.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2391735>11 points</span> by <a href="user?id=emmanuelory">emmanuelory</a> 5 hours ago | <a href="item?id=2391735">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">74.</td><td><center><a id=up_2392012 href="vote?for=2392012&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392012></span></center></td><td class="title"><a href="http://techcrunch.com/2011/03/31/qwiki-raises-1-million-from-fund-started-by-groupon-co-founders/">Qwiki Raises $1 Million From Groupon Co-Founders</a><span class="comhead"> (techcrunch.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392012>8 points</span> by <a href="user?id=kacy">kacy</a> 4 hours ago | <a href="item?id=2392012">1 comment</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">75.</td><td><center><a id=up_2392592 href="vote?for=2392592&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392592></span></center></td><td class="title"><a href="http://www.airs.com/blog/archives/495" rel="nofollow">Tcl: a brief overview of language design gone wrong</a><span class="comhead"> (airs.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392592>4 points</span> by <a href="user?id=yan">yan</a> 2 hours ago | <a href="item?id=2392592">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">76.</td><td><center><a id=up_2392565 href="vote?for=2392565&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392565></span></center></td><td class="title"><a href="http://www.slate.com/id/2289302" rel="nofollow">Against Gamification</a><span class="comhead"> (slate.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392565>4 points</span> by <a href="user?id=mcantelon">mcantelon</a> 2 hours ago | <a href="item?id=2392565">4 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">77.</td><td><center><a id=up_2392667 href="vote?for=2392667&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392667></span></center></td><td class="title"><a href="http://mashable.com/2011/03/31/activeinbox/">ActiveInbox Turns Gmail Into a Task Manager</a><span class="comhead"> (mashable.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392667>13 points</span> by <a href="user?id=peterjlambert">peterjlambert</a> 2 hours ago | <a href="item?id=2392667">3 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">78.</td><td><center><a id=up_2392353 href="vote?for=2392353&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392353></span></center></td><td class="title"><a href="http://pivotrly.com/" rel="nofollow">Pivotrly</a><span class="comhead"> (pivotrly.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392353>5 points</span> by <a href="user?id=citadrianne">citadrianne</a> 3 hours ago | <a href="item?id=2392353">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">79.</td><td><center><a id=up_2392412 href="vote?for=2392412&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392412></span></center></td><td class="title"><a href="http://blog.indextank.com/546/contest-time-build-an-app-with-indextank-factual/">Contest time. Build an app with IndexTank + Factual</a><span class="comhead"> (indextank.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392412>17 points</span> by <a href="user?id=diego">diego</a> 3 hours ago | <a href="item?id=2392412">3 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">80.</td><td><center><a id=up_2392392 href="vote?for=2392392&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392392></span></center></td><td class="title"><a href="http://bostinnovation.com/2011/03/31/boston-companies-using-django/">Boston Companies Using Django</a><span class="comhead"> (bostinnovation.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392392>17 points</span> by <a href="user?id=kmccarth">kmccarth</a> 3 hours ago | <a href="item?id=2392392">3 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">81.</td><td><center><a id=up_2391777 href="vote?for=2391777&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2391777></span></center></td><td class="title"><a href="https://github.com/williscool/jquery-socket.io">Socket.io jquery plugin</a><span class="comhead"> (github.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2391777>9 points</span> by <a href="user?id=wh-uws">wh-uws</a> 5 hours ago | <a href="item?id=2391777">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">82.</td><td><center><a id=up_2391758 href="vote?for=2391758&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2391758></span></center></td><td class="title"><a href="https://github.com/karlseguin/the-little-mongodb-book/network">Github, the future of book publishing?</a><span class="comhead"> (github.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2391758>28 points</span> by <a href="user?id=latch">latch</a> 5 hours ago | <a href="item?id=2391758">22 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">83.</td><td><center><a id=up_2393294 href="vote?for=2393294&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2393294></span></center></td><td class="title"><a href="item?id=2393294">Ask HN: Anyone recommend BaseCampHQ alternatives?</a></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2393294>3 points</span> by <a href="user?id=allanchao">allanchao</a> 47 minutes ago | <a href="item?id=2393294">3 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">84.</td><td><center><a id=up_2392727 href="vote?for=2392727&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392727></span></center></td><td class="title"><a href="http://www.theregister.co.uk/2011/03/31/google_juices_both_python_and_java_app_engine/" rel="nofollow">Google app cloud juices Java and Python</a><span class="comhead"> (theregister.co.uk) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392727>3 points</span> by <a href="user?id=sunsai">sunsai</a> 2 hours ago | <a href="item?id=2392727">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">85.</td><td><center><a id=up_2391744 href="vote?for=2391744&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2391744></span></center></td><td class="title"><a href="http://techcrunch.com/2011/03/31/what%E2%80%99s-the-most-difficult-ceo-skill-managing-your-own-psychology/">Is Your Mind Playing Tricks on You?</a><span class="comhead"> (techcrunch.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2391744>8 points</span> by <a href="user?id=Stormi">Stormi</a> 5 hours ago | <a href="item?id=2391744">1 comment</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">86.</td><td><center><a id=up_2392586 href="vote?for=2392586&didir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392586></span></center></td><td class="title"><a href="item?id=2392586">Show HN: an app to help you shop for food</a></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392586>9 points</span> by <a href="user?id=maxhs">maxhs</a> 2 hours ago | <a href="item?id=2392586">3 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">87.</td><td><center><a id=up_2392230 href="vote?for=2392230&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2392230></span></center></td><td class="title"><a href="http://www.nodesocket.com/survey.php" rel="nofollow"> Help Us Build A World-Class Node.js Hosting Platform</a><span class="comhead"> (nodesocket.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2392230>6 points</span> by <a href="user?id=nodesocket">nodesocket</a> 4 hours ago | <a href="item?id=2392230">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">88.</td><td><center><a id=up_2390467 href="vote?for=2390467&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2390467></span></center></td><td class="title"><a href="http://www.businessweek.com/magazine/content/11_15/b4223041200216.htm">Do Not Anger the Alpha Android</a><span class="comhead"> (businessweek.com) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2390467>36 points</span> by <a href="user?id=pathik">pathik</a> 15 hours ago | <a href="item?id=2390467">31 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">89.</td><td><center><a id=up_2385424 href="vote?for=2385424&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2385424></span></center></td><td class="title"><a href="http://devinterviews.pen.io/">Hiring Developers: You're Doing It Wrong</a><span class="comhead"> (pen.io) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2385424>380 points</span> by <a href="user?id=Udo">Udo</a> 1 day ago | <a href="item?id=2385424">205 comments</a></td></tr><tr style="height:5px"></tr><tr><td align=right valign=top class="title">90.</td><td><center><a id=up_2387330 href="vote?for=2387330&dir=up&whence=%2f%78%3f%66%6e%69%64%3d%48%58%51%7a%4c%70%6f%47%57%41"><img src="http://ycombinator.com/images/grayarrow.gif" border=0 vspace=3 hspace=2></a><span id=down_2387330></span></center></td><td class="title"><a href="http://ignorethecode.net/blog/2011/03/30/skype_5/">Skype 5 for Mac</a><span class="comhead"> (ignorethecode.net) </span></td></tr><tr><td colspan=2></td><td class="subtext"><span id=score_2387330>265 points</span> by <a href="user?id=shawndumas">shawndumas</a> 1 day ago | <a href="item?id=2387330">110 comments</a></td></tr><tr style="height:5px"></tr><tr style="height:10px"></tr><tr><td colspan=2></td><td class="title"><a href="/x?fnid=bXOjmlABF8" rel="nofollow">More</a></td></tr></table></td></tr><tr><td><img src="http://ycombinator.com/images/s.gif" height=10 width=0><table width="100%" cellspacing=0 cellpadding=1><tr><td bgcolor=#ff6600></td></tr></table><br>
|
28
|
+
<center><span class="yclinks"><a href="lists">Lists</a> | <a href="rss">RSS</a> | <a href="http://google.com/search?q=site%3Anews.ycombinator.com">Search</a> | <a href="http://ycombinator.com/bookmarklet.html">Bookmarklet</a> | <a href="http://ycombinator.com/newsguidelines.html">Guidelines</a> | <a href="http://ycombinator.com/newsfaq.html">FAQ</a> | <a href="http://ycombinator.com/newsnews.html">News News</a> | <a href="item?id=363">Feature Requests</a> | <a href="http://ycombinator.com">Y Combinator</a> | <a href="http://ycombinator.com/apply.html">Apply</a> | <a href="http://ycombinator.com/lib.html">Library</a></span><br><br>
|
29
|
+
<script type="text/javascript"
|
30
|
+
src="http://www.co2stats.com/propres.php?s=1138"></script><img src="http://ycombinator.com/images/s.gif" height=1 width=15><a href="http://www.webmynd.com/html/hackernews.html"><img
|
31
|
+
src="http://ycombinator.com/images/hnsearch.png" border=0
|
32
|
+
style="padding-bottom:12px"></a><img src="http://ycombinator.com/images/s.gif" height=1 width=25><a href="http://mixpanel.com/?from=yc"><img border=0
|
33
|
+
src="http://mixpanel.com/site_media/images/mixpanel_partner_logo_borderless.gif"
|
34
|
+
alt="Analytics by Mixpanel"
|
35
|
+
style="padding-bottom:8px"
|
36
|
+
/></a><br>
|
37
|
+
</center></td></tr></table></center></body></html>
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
require 'hacker_news'
|
15
|
+
require 'fakeweb'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestScraper < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_should_get_articles
|
6
|
+
FakeWeb.register_uri(:get, %r|http://news.ycombinator.com|, :body => File.read(File.dirname(__FILE__) + "/../fixtures/index.html"))
|
7
|
+
articles = HackerNews::Scraper.articles
|
8
|
+
assert_equal 150, articles.size
|
9
|
+
first_article = articles[0]
|
10
|
+
|
11
|
+
assert_equal "Apple’s boring hardware updates", first_article.title
|
12
|
+
assert_equal 1, first_article.position
|
13
|
+
assert_equal 127, first_article.points
|
14
|
+
assert_equal 59, first_article.comments
|
15
|
+
assert_equal 2389994, first_article.id
|
16
|
+
assert_equal "remi", first_article.user
|
17
|
+
assert_equal "http://www.marco.org/4222285032", first_article.url
|
18
|
+
assert_equal "19 hours ago", first_article.created_at
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hacker_news
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Aleksandr Lossenko
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-04-01 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ~>
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
segments:
|
26
|
+
- 1
|
27
|
+
- 4
|
28
|
+
- 0
|
29
|
+
version: 1.4.0
|
30
|
+
prerelease: false
|
31
|
+
type: :runtime
|
32
|
+
name: nokogiri
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
prerelease: false
|
43
|
+
type: :runtime
|
44
|
+
name: iconv
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ~>
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 1
|
53
|
+
- 0
|
54
|
+
- 0
|
55
|
+
version: 1.0.0
|
56
|
+
prerelease: false
|
57
|
+
type: :development
|
58
|
+
name: bundler
|
59
|
+
version_requirements: *id003
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
segments:
|
66
|
+
- 1
|
67
|
+
- 5
|
68
|
+
- 2
|
69
|
+
version: 1.5.2
|
70
|
+
prerelease: false
|
71
|
+
type: :development
|
72
|
+
name: jeweler
|
73
|
+
version_requirements: *id004
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
prerelease: false
|
83
|
+
type: :development
|
84
|
+
name: rcov
|
85
|
+
version_requirements: *id005
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
prerelease: false
|
95
|
+
type: :development
|
96
|
+
name: fakeweb
|
97
|
+
version_requirements: *id006
|
98
|
+
description: Fetches newest 5 pages from Hacker News and returns convenient ruby objects
|
99
|
+
email: aleksandr.lossenko@gmail.com
|
100
|
+
executables: []
|
101
|
+
|
102
|
+
extensions: []
|
103
|
+
|
104
|
+
extra_rdoc_files:
|
105
|
+
- LICENSE.txt
|
106
|
+
- README
|
107
|
+
- README.rdoc
|
108
|
+
files:
|
109
|
+
- .document
|
110
|
+
- Gemfile
|
111
|
+
- Gemfile.lock
|
112
|
+
- LICENSE.txt
|
113
|
+
- README
|
114
|
+
- README.rdoc
|
115
|
+
- Rakefile
|
116
|
+
- VERSION
|
117
|
+
- lib/hacker_news.rb
|
118
|
+
- lib/hacker_news/item.rb
|
119
|
+
- lib/hacker_news/scraper.rb
|
120
|
+
- test/fixtures/index.html
|
121
|
+
- test/helper.rb
|
122
|
+
- test/unit/test_scraper.rb
|
123
|
+
has_rdoc: true
|
124
|
+
homepage: http://github.com/egze/hacker_news
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
version: "0"
|
146
|
+
requirements: []
|
147
|
+
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 1.3.6
|
150
|
+
signing_key:
|
151
|
+
specification_version: 3
|
152
|
+
summary: Wrapper for Hacker News website
|
153
|
+
test_files:
|
154
|
+
- test/helper.rb
|
155
|
+
- test/unit/test_scraper.rb
|