hckr 0.0.1
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 +15 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/bin/hckr +33 -0
- data/hckr.gemspec +25 -0
- data/lib/hckr.rb +10 -0
- data/lib/hckr/document.rb +25 -0
- data/lib/hckr/json_builder.rb +14 -0
- data/lib/hckr/runner.rb +29 -0
- data/lib/hckr/scraper.rb +33 -0
- data/lib/hckr/version.rb +3 -0
- data/spec/fixtures/page.html +22 -0
- data/spec/hckr/json_builder_spec.rb +8 -0
- data/spec/hckr/scraper_spec.rb +19 -0
- data/spec/spec_helper.rb +4 -0
- metadata +124 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
MzdmZGE3Y2UwNWQwZmJiZTNhNWQwNTM4MjI3MDIxODg0M2Y0ZDY4Nw==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
M2FhM2JkMzM2ZjNjYTFkOGRkYjRiMWVhMTkzMThjZGIyMzVkZmI3ZQ==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
MTY4OTQxNjgxOTIyYWZlNDdhZWNmYWRkZjk0ZjNiMDlkZDcwNDVmMGY4Mzlj
|
|
10
|
+
N2NjOTNmNjY4ZDJjY2ZiMDJkZWE2MjdmZTg4ZDZhZTZjZWNhZDRhYTBjOWI3
|
|
11
|
+
Yjk0YmE4ZWQ5ZWE3NzMzOGQ3YmI1MWQ4NDNlMjFiOThkMGZhZGU=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
MDNhYTRiMDYxNDAwYTllNGY5OGIwZWY2NWY5NTZmMTQxYjUyZTc5NTE5NjJl
|
|
14
|
+
NmQxOGRmYzlmYTJhMDhjMWYwZmNmNDA4NGQ4MjJkMDc1Y2Q1OTVkZDFlNWQ3
|
|
15
|
+
OWFhM2JmYWE3ZThlOGVkYmU0ODJkNDA5NzllZmFiMGFmNjI4Yzc=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.9.3-p392
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014 Ile Eftimov
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Hckr
|
|
2
|
+
|
|
3
|
+
Browse Hackernews from the command line. Or get some JSON.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
gem 'hckr'
|
|
10
|
+
|
|
11
|
+
And then execute:
|
|
12
|
+
|
|
13
|
+
$ bundle
|
|
14
|
+
|
|
15
|
+
Or install it yourself as:
|
|
16
|
+
|
|
17
|
+
$ gem install hckr
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Via CLI
|
|
22
|
+
Run ```hckr```
|
|
23
|
+
|
|
24
|
+
#### Options
|
|
25
|
+
|
|
26
|
+
* ```home```, ```-h``` or ```--home``` returns links from the Show HN page
|
|
27
|
+
* ```show```, ```-s``` or ```--show``` returns links from the Show HN page
|
|
28
|
+
* ```jobs```, ```-j``` or ```--jobs``` returns links from the jobs section
|
|
29
|
+
* ```newest```, ```-n``` or ```--newest``` returns links from the newest section
|
|
30
|
+
* ```best```, ```-b``` or ```--best``` returns links from the best section
|
|
31
|
+
* ```help``` or ```--help``` sends help
|
|
32
|
+
|
|
33
|
+
When ran without any arguments, returns links from the home page.
|
|
34
|
+
|
|
35
|
+
### Return JSON
|
|
36
|
+
You can call the ```Hckr::JsonBuilder``` like:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
Hckr::JsonBuilder.new(page: :jobs).build!
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
which will return a JSON of the jobs HN page.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Contributing
|
|
46
|
+
|
|
47
|
+
1. Fork it ( http://github.com/fteem/hckr/fork )
|
|
48
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
49
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
50
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
51
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/hckr
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
path = File.expand_path(File.dirname(__FILE__))
|
|
5
|
+
$:<< "#{path}/../lib"
|
|
6
|
+
|
|
7
|
+
require 'hckr'
|
|
8
|
+
|
|
9
|
+
case ARGV[0]
|
|
10
|
+
when "show", "-s", "--show"
|
|
11
|
+
Hckr::Runner.new(page: :show).run!
|
|
12
|
+
when "jobs", "-j", "--jobs"
|
|
13
|
+
Hckr::Runner.new(page: :jobs).run!
|
|
14
|
+
when "newest", "-n", "--newest"
|
|
15
|
+
Hckr::Runner.new(page: :newest).run!
|
|
16
|
+
when "best", "-b", "--best"
|
|
17
|
+
Hckr::Runner.new(page: :best).run!
|
|
18
|
+
when "home", "-h", "--home"
|
|
19
|
+
Hckr::Runner.new(page: :default).run!
|
|
20
|
+
when "help", "--help"
|
|
21
|
+
puts "\nUsage: hckr [OPTION]"
|
|
22
|
+
puts "\n\tBrowse Hackernews in terminal."
|
|
23
|
+
puts "\nExample: hckr --jobs"
|
|
24
|
+
puts "\nOptions:"
|
|
25
|
+
puts "show/-s/--show \t \t returns Show HN page."
|
|
26
|
+
puts "jobs/-j/--jobs \t returns HN jobs page."
|
|
27
|
+
puts "best/-b/--best \t returns HN best page."
|
|
28
|
+
puts "newest/-n/--newest \t returns newest HN posts page."
|
|
29
|
+
puts "*no options* \t\t returns the HN homepage."
|
|
30
|
+
puts "\n"
|
|
31
|
+
else
|
|
32
|
+
Hckr::Runner.new(page: :default).run!
|
|
33
|
+
end
|
data/hckr.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'hckr/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "hckr"
|
|
8
|
+
spec.version = Hckr::VERSION
|
|
9
|
+
spec.authors = ["Ile Eftimov"]
|
|
10
|
+
spec.email = ["ileeftimov@gmail.com"]
|
|
11
|
+
spec.summary = %q{Browse Hackernews via CLI.}
|
|
12
|
+
spec.description = %q{Browse Hackernews via CLI. Or get some JSON love.}
|
|
13
|
+
spec.homepage = "http://github.com/fteem/hckr"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
|
22
|
+
spec.add_development_dependency "rake"
|
|
23
|
+
spec.add_development_dependency 'rspec'
|
|
24
|
+
spec.add_dependency 'nokogiri'
|
|
25
|
+
end
|
data/lib/hckr.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Hckr
|
|
2
|
+
class Document
|
|
3
|
+
DEFAULT_URL = "https://news.ycombinator.com"
|
|
4
|
+
NEWEST_URL = "#{DEFAULT_URL}/newest"
|
|
5
|
+
BEST_URL = "#{DEFAULT_URL}/best"
|
|
6
|
+
SHOW_URL = "#{DEFAULT_URL}/show"
|
|
7
|
+
JOBS_URL = "#{DEFAULT_URL}/jobs"
|
|
8
|
+
|
|
9
|
+
def self.fetch!(arg)
|
|
10
|
+
case arg[:page]
|
|
11
|
+
when :newest
|
|
12
|
+
Nokogiri::HTML(open(NEWEST_URL))
|
|
13
|
+
when :best
|
|
14
|
+
Nokogiri::HTML(open(BEST_URL))
|
|
15
|
+
when :show
|
|
16
|
+
Nokogiri::HTML(open(SHOW_URL))
|
|
17
|
+
when :jobs
|
|
18
|
+
Nokogiri::HTML(open(JOBS_URL))
|
|
19
|
+
else
|
|
20
|
+
Nokogiri::HTML(open(DEFAULT_URL))
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/hckr/runner.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Hckr
|
|
2
|
+
class Runner
|
|
3
|
+
|
|
4
|
+
def initialize type
|
|
5
|
+
@type = type
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def run!
|
|
9
|
+
greeting
|
|
10
|
+
links = Hckr::Scraper.new(@type).scrape!
|
|
11
|
+
links.each do |hash|
|
|
12
|
+
print_link_info(hash)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def greeting
|
|
19
|
+
greeting = "Currently, top links on HN. (Cmd/Ctrl + double click on a link to open it in browser)"
|
|
20
|
+
puts greeting
|
|
21
|
+
puts "=" * greeting.length
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def print_link_info(link)
|
|
25
|
+
puts "#{link[:name]} - #{link[:href]}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/hckr/scraper.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Hckr
|
|
2
|
+
class Scraper
|
|
3
|
+
|
|
4
|
+
def initialize(type)
|
|
5
|
+
@doc = Hckr::Document.fetch!(type)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def scrape!
|
|
9
|
+
links.inject([]) do |collection, link|
|
|
10
|
+
collection << extract_data(link)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
def links
|
|
16
|
+
# Slicing off the last link since it's the 'More' link
|
|
17
|
+
@doc.css('.title').search('a')[0..-2]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def extract_data(link)
|
|
21
|
+
{ name: extract_name(link), href: extract_href(link) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def extract_href(link)
|
|
25
|
+
link.attr("href")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def extract_name(link)
|
|
29
|
+
link.text
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/hckr/version.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<html><head><meta name="referrer" content="origin"></meta><link rel="stylesheet" type="text/css" href="news.css?D5xomo4AnfUU6lV1AkTD"></link><link rel="shortcut icon" href="favicon.ico"></link><link rel="alternate" type="application/rss+xml" title="RSS" href="rss"></link><script type="text/javascript">
|
|
2
|
+
function byId(id) {
|
|
3
|
+
return document.getElementById(id);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function vote(node) {
|
|
7
|
+
var v = node.id.split(/_/); // {'up', '123'}
|
|
8
|
+
var item = v[1];
|
|
9
|
+
|
|
10
|
+
// hide arrows
|
|
11
|
+
byId('up_' + item).style.visibility = 'hidden';
|
|
12
|
+
byId('down_' + item).style.visibility = 'hidden';
|
|
13
|
+
|
|
14
|
+
// ping server
|
|
15
|
+
var ping = new Image();
|
|
16
|
+
ping.src = node.href;
|
|
17
|
+
|
|
18
|
+
return false; // cancel browser nav
|
|
19
|
+
} </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://www.ycombinator.com"><img src="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="s.gif" height="1" width="10"><a href="newest">new</a> | <a href="newcomments">comments</a> | <a href="show">show</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="newslogin?whence=%6e%65%77%73">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">1.</td><td><center><a id="up_8050106" href="vote?for=8050106&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050106"></span></center></td><td class="title"><a href="http://www.newyorker.com/reporting/2014/07/21/140721fa_fact_mnookin">Thanks, HN: You helped discover a disease and save lives. Sincerely, @mattmight</a><span class="comhead"> (newyorker.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050106">239 points</span> by <a href="user?id=mattmight">mattmight</a> 1 hour ago | <a href="item?id=8050106">22 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">2.</td><td><center><a id="up_8050144" href="vote?for=8050144&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050144"></span></center></td><td class="title"><a href="http://facebook.github.io/react/blog/2014/07/17/react-v0.11.html">React v0.11</a><span class="comhead"> (facebook.github.io) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050144">64 points</span> by <a href="user?id=spicyj">spicyj</a> 1 hour ago | <a href="item?id=8050144">11 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">3.</td><td><center><a id="up_8049180" href="vote?for=8049180&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049180"></span></center></td><td class="title"><a href="http://lists.openwall.net/linux-kernel/2014/07/17/235">The getrandom(2) system call was requested by the LibreSSL Portable developers</a><span class="comhead"> (openwall.net) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049180">132 points</span> by <a href="user?id=gnuvince">gnuvince</a> 4 hours ago | <a href="item?id=8049180">60 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">4.</td><td><center><a id="up_8049973" href="vote?for=8049973&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049973"></span></center></td><td class="title"><a href="http://online.wsj.com/articles/google-reports-22-revenue-growth-1405628219">Google Reports 22% Revenue Growth</a><span class="comhead"> (wsj.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049973">48 points</span> by <a href="user?id=reflect">reflect</a> 1 hour ago | <a href="item?id=8049973">28 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">5.</td><td><center><a id="up_8050157" href="vote?for=8050157&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050157"></span></center></td><td class="title"><a href="http://priceonomics.com/the-big-winner-from-y-combinators-success-sequoia/">The Big Winner from Y Combinator’s Success? Sequoia Capital</a><span class="comhead"> (priceonomics.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050157">24 points</span> by <a href="user?id=ryan_j_naughton">ryan_j_naughton</a> 1 hour ago | <a href="item?id=8050157">5 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">6.</td><td><center><a id="up_8049694" href="vote?for=8049694&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049694"></span></center></td><td class="title"><a href="http://www.vox.com/2014/7/16/5909709/the-un-thinks-well-hit-peak-births-in-2014">The UN thinks we could hit peak births in 2014</a><span class="comhead"> (vox.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049694">53 points</span> by <a href="user?id=prostoalex">prostoalex</a> 2 hours ago | <a href="item?id=8049694">11 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">7.</td><td><center><a id="up_8048997" href="vote?for=8048997&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048997"></span></center></td><td class="title"><a href="http://blog.level3.com/global-connectivity/verizons-accidental-mea-culpa">Verizon's accidental mea culpa</a><span class="comhead"> (level3.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048997">521 points</span> by <a href="user?id=shimshim">shimshim</a> 4 hours ago | <a href="item?id=8048997">196 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">8.</td><td><center><a id="up_8048413" href="vote?for=8048413&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048413"></span></center></td><td class="title"><a href="http://steady.stupeflix.com/">Show HN: Steady – Shoot Cinematic Videos</a><span class="comhead"> (stupeflix.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048413">117 points</span> by <a href="user?id=trueduke">trueduke</a> 5 hours ago | <a href="item?id=8048413">66 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">9.</td><td><center><a id="up_8048014" href="vote?for=8048014&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048014"></span></center></td><td class="title"><a href="http://nimrod-by-example.github.io/">Nimrod by Example</a><span class="comhead"> (nimrod-by-example.github.io) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048014">120 points</span> by <a href="user?id=def-">def-</a> 6 hours ago | <a href="item?id=8048014">41 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">10.</td><td><center><a id="up_8049890" href="vote?for=8049890&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049890"></span></center></td><td class="title"><a href="http://newsoffice.mit.edu/2014/own-your-own-data-0709">Own your own data</a><span class="comhead"> (mit.edu) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049890">20 points</span> by <a href="user?id=dalek2point3">dalek2point3</a> 2 hours ago | <a href="item?id=8049890">5 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">11.</td><td><center><a id="up_8048925" href="vote?for=8048925&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048925"></span></center></td><td class="title"><a href="https://lists.debian.org/debian-security-announce/2014/msg00161.html">Fail2ban security update</a><span class="comhead"> (debian.org) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048925">61 points</span> by <a href="user?id=TimWolla">TimWolla</a> 4 hours ago | <a href="item?id=8048925">26 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">12.</td><td><center><a id="up_8048866" href="vote?for=8048866&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048866"></span></center></td><td class="title"><a href="http://recode.net/2014/07/17/microsoft-to-shut-down-xbox-entertainment-studios/">Microsoft to Shutter Xbox Entertainment Studios</a><span class="comhead"> (recode.net) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048866">61 points</span> by <a href="user?id=blacktulip">blacktulip</a> 4 hours ago | <a href="item?id=8048866">28 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">13.</td><td><center><a id="up_8050457" href="vote?for=8050457&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050457"></span></center></td><td class="title"><a href="https://goroost.com/hackernews" rel="nofollow">Show HN: HackerNews web push for stories with 100+ upvotes by Roost (YC S14)</a><span class="comhead"> (goroost.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050457">12 points</span> by <a href="user?id=millisecond">millisecond</a> 16 minutes ago | <a href="item?id=8050457">1 comment</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">14.</td><td><center><a id="up_8049686" href="vote?for=8049686&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049686"></span></center></td><td class="title"><a href="http://en.wikipedia.org/wiki/Pigeon_photography">Pigeon photography</a><span class="comhead"> (wikipedia.org) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049686">27 points</span> by <a href="user?id=josephpmay">josephpmay</a> 2 hours ago | <a href="item?id=8049686">5 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">15.</td><td><center><a id="up_8047406" href="vote?for=8047406&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8047406"></span></center></td><td class="title"><a href="http://www.gamasutra.com/view/feature/129947/the_history_of_civilization.php?print=1">The History of Civilization</a><span class="comhead"> (gamasutra.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8047406">141 points</span> by <a href="user?id=gdubs">gdubs</a> 8 hours ago | <a href="item?id=8047406">63 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">16.</td><td></td><td class="title"><a href="http://www.jobscore.com/jobs2/smartasset/senior-experience-architect-ui-ux/c-tV0wUf8r47tmiGakhP3Q" rel="nofollow">SmartAsset (YC S12) Hiring Senior Interaction Designer</a><span class="comhead"> (jobscore.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext">1 hour ago</td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">17.</td><td><center><a id="up_8050405" href="vote?for=8050405&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050405"></span></center></td><td class="title"><a href="http://www.sultanik.com/blog/RandomSolutions" rel="nofollow">Random Solutions are Often Good Enough</a><span class="comhead"> (sultanik.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050405">5 points</span> by <a href="user?id=luu">luu</a> 26 minutes ago | <a href="item?id=8050405">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">18.</td><td><center><a id="up_8047647" href="vote?for=8047647&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8047647"></span></center></td><td class="title"><a href="http://techcrunch.com/2014/07/17/product-hunt-the-popular-tech-product-discovery-site-is-in-current-y-combinator-batch/">Product Hunt Is in Current Y Combinator Batch</a><span class="comhead"> (techcrunch.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8047647">148 points</span> by <a href="user?id=spountzy">spountzy</a> 7 hours ago | <a href="item?id=8047647">86 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">19.</td><td><center><a id="up_8050164" href="vote?for=8050164&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050164"></span></center></td><td class="title"><a href="http://www.csmonitor.com/World/Europe/2014/0717/Web-evidence-points-to-pro-Russia-rebels-in-downing-of-MH17">Web evidence points to pro-Russia rebels in downing of MH17</a><span class="comhead"> (csmonitor.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050164">137 points</span> by <a href="user?id=greglindahl">greglindahl</a> 1 hour ago | <a href="item?id=8050164">53 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">20.</td><td><center><a id="up_8049098" href="vote?for=8049098&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049098"></span></center></td><td class="title"><a href="https://www.facebook.com/business/news/Discover-and-Buy-Products-on-Facebook-Test">Testing a New Way to Discover and Buy Products on Facebook</a><span class="comhead"> (facebook.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049098">36 points</span> by <a href="user?id=arrel">arrel</a> 4 hours ago | <a href="item?id=8049098">19 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">21.</td><td><center><a id="up_8048229" href="vote?for=8048229&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048229"></span></center></td><td class="title"><a href="http://www.dfs.ny.gov/about/press2014/pr1407171-vc.pdf">Proposed New York State Virtual Currency Regulations [pdf]</a><span class="comhead"> (ny.gov) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048229">59 points</span> by <a href="user?id=mdelias">mdelias</a> 6 hours ago | <a href="item?id=8048229">23 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">22.</td><td><center><a id="up_8046849" href="vote?for=8046849&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8046849"></span></center></td><td class="title"><a href="https://www.kickstarter.com/projects/tomchristie/django-rest-framework-3">Django REST framework 3</a><span class="comhead"> (kickstarter.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8046849">141 points</span> by <a href="user?id=tomchristie">tomchristie</a> 11 hours ago | <a href="item?id=8046849">16 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">23.</td><td><center><a id="up_8046684" href="vote?for=8046684&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8046684"></span></center></td><td class="title"><a href="https://docs.google.com/document/d/1v4Oqa0WwHunqlb8C3ObL_uNQw3DfSY-ztoA-4wWbKcg/pub">Simpler and faster GC for Go</a><span class="comhead"> (docs.google.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8046684">161 points</span> by <a href="user?id=xkarga00">xkarga00</a> 12 hours ago | <a href="item?id=8046684">25 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">24.</td><td><center><a id="up_8049758" href="vote?for=8049758&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8049758"></span></center></td><td class="title"><a href="http://ruudvanasseldonk.com/2014/07/17/one-year-with-colemak">One year with Colemak</a><span class="comhead"> (ruudvanasseldonk.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8049758">13 points</span> by <a href="user?id=vdloo">vdloo</a> 2 hours ago | <a href="item?id=8049758">24 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">25.</td><td><center><a id="up_8047336" href="vote?for=8047336&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8047336"></span></center></td><td class="title"><a href="http://featherweightmusings.blogspot.com/2014/07/rust-for-c-programmers-part-9.html?m=1">Rust for C++ Programmers – Part 9</a><span class="comhead"> (featherweightmusings.blogspot.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8047336">66 points</span> by <a href="user?id=valarauca1">valarauca1</a> 8 hours ago | <a href="item?id=8047336">1 comment</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">26.</td><td><center><a id="up_8046526" href="vote?for=8046526&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8046526"></span></center></td><td class="title"><a href="http://pubs.usgs.gov/sim/3292/">Geologic Map of Mars</a><span class="comhead"> (usgs.gov) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8046526">74 points</span> by <a href="user?id=chton">chton</a> 13 hours ago | <a href="item?id=8046526">19 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">27.</td><td><center><a id="up_8047231" href="vote?for=8047231&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8047231"></span></center></td><td class="title"><a href="https://github.com/appnician/pastor">Show HN: Pastor generates and stores passwords without storing any passwords</a><span class="comhead"> (github.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8047231">58 points</span> by <a href="user?id=Appnician">Appnician</a> 9 hours ago | <a href="item?id=8047231">66 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">28.</td><td><center><a id="up_8050320" href="vote?for=8050320&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8050320"></span></center></td><td class="title"><a href="http://www.cipherdyne.org/fwknop/" rel="nofollow">Single Packet Authorization and Port Knocking (fwknop)</a><span class="comhead"> (cipherdyne.org) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8050320">3 points</span> by <a href="user?id=kolev">kolev</a> 41 minutes ago | <a href="item?id=8050320">discuss</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">29.</td><td><center><a id="up_8048513" href="vote?for=8048513&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8048513"></span></center></td><td class="title"><a href="http://minimsft.blogspot.com/2014/07/18000-microsoft-jobs-gone-eventually.html">18,000 Microsoft Jobs Gone Eventually?</a><span class="comhead"> (minimsft.blogspot.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8048513">38 points</span> by <a href="user?id=programminggeek">programminggeek</a> 5 hours ago | <a href="item?id=8048513">4 comments</a></td></tr><tr style="height:5px"></tr><tr><td align="right" valign="top" class="title">30.</td><td><center><a id="up_8046505" href="vote?for=8046505&dir=up&whence=%6e%65%77%73"><div class="votearrow" title="upvote"></div></a><span id="down_8046505"></span></center></td><td class="title"><a href="http://microjs.com/">Microjs: JavaScript Micro-Frameworks and Micro-Libraries</a><span class="comhead"> (microjs.com) </span></td></tr><tr><td colspan="2"></td><td class="subtext"><span id="score_8046505">132 points</span> by <a href="user?id=arindammanidas">arindammanidas</a> 13 hours ago | <a href="item?id=8046505">22 comments</a></td></tr><tr style="height:5px"></tr><tr style="height:10px"></tr><tr><td colspan="2"></td><td class="title"><a href="news2">More</a></td></tr></table></td></tr><tr><td><img src="s.gif" height="10" width="0"><table width="100%" cellspacing="0" cellpadding="1"><tr><td bgcolor="#ff6600"></td></tr></table><br>
|
|
20
|
+
<center><span class="yclinks"><a href="newsguidelines.html">Guidelines</a> | <a href="newsfaq.html">FAQ</a> | <a href="lists">Lists</a> | <a href="bookmarklet.html">Bookmarklet</a> | <a href="dmca.html">DMCA</a> | <a href="newsnews.html">News News</a> | <a href="https://github.com/HackerNews/HN/issues">Bugs and Feature Requests</a> | <a href="http://www.ycombinator.com/">Y Combinator</a> | <a href="http://www.ycombinator.com/apply/">Apply</a> | <a href="http://www.ycombinator.com/resources/">Library</a> | <a href="http://www.ycombinator.com/contact/">Contact</a></span><br><br>
|
|
21
|
+
<form method="get" action="//hn.algolia.com/">Search: <input type="text" name="q" value="" size="17"></form><br>
|
|
22
|
+
</center></td></tr></table></center></body></html>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Hckr::JsonBuilder do
|
|
4
|
+
it 'builds JSON out of scraping results' do
|
|
5
|
+
Hckr::Document.should_receive(:open).and_return(File.open('./spec/fixtures/page.html').read)
|
|
6
|
+
expect(described_class.new(page: :newest).build!).to be_kind_of(String)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Hckr::Scraper do
|
|
4
|
+
before :each do
|
|
5
|
+
Hckr::Document.should_receive(:open).and_return(File.open('./spec/fixtures/page.html').read)
|
|
6
|
+
@links = Hckr::Scraper.new(page: :newest).scrape!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'scapes the links off the page' do
|
|
10
|
+
expect(@links).to be_kind_of Array
|
|
11
|
+
expect(@links.first).to be_kind_of Hash
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'link has name and href' do
|
|
15
|
+
expect(@links.first[:href]).to eq "http://www.newyorker.com/reporting/2014/07/21/140721fa_fact_mnookin"
|
|
16
|
+
expect(@links.first[:name]).to eq "Thanks, HN: You helped discover a disease and save lives. Sincerely, @mattmight"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: hckr
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ile Eftimov
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-08-01 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.5'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.5'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ! '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ! '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ! '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: nokogiri
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ! '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
description: Browse Hackernews via CLI. Or get some JSON love.
|
|
70
|
+
email:
|
|
71
|
+
- ileeftimov@gmail.com
|
|
72
|
+
executables:
|
|
73
|
+
- hckr
|
|
74
|
+
extensions: []
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
files:
|
|
77
|
+
- .gitignore
|
|
78
|
+
- .rspec
|
|
79
|
+
- .ruby-version
|
|
80
|
+
- Gemfile
|
|
81
|
+
- LICENSE.txt
|
|
82
|
+
- README.md
|
|
83
|
+
- Rakefile
|
|
84
|
+
- bin/hckr
|
|
85
|
+
- hckr.gemspec
|
|
86
|
+
- lib/hckr.rb
|
|
87
|
+
- lib/hckr/document.rb
|
|
88
|
+
- lib/hckr/json_builder.rb
|
|
89
|
+
- lib/hckr/runner.rb
|
|
90
|
+
- lib/hckr/scraper.rb
|
|
91
|
+
- lib/hckr/version.rb
|
|
92
|
+
- spec/fixtures/page.html
|
|
93
|
+
- spec/hckr/json_builder_spec.rb
|
|
94
|
+
- spec/hckr/scraper_spec.rb
|
|
95
|
+
- spec/spec_helper.rb
|
|
96
|
+
homepage: http://github.com/fteem/hckr
|
|
97
|
+
licenses:
|
|
98
|
+
- MIT
|
|
99
|
+
metadata: {}
|
|
100
|
+
post_install_message:
|
|
101
|
+
rdoc_options: []
|
|
102
|
+
require_paths:
|
|
103
|
+
- lib
|
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - ! '>='
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '0'
|
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
|
+
requirements:
|
|
111
|
+
- - ! '>='
|
|
112
|
+
- !ruby/object:Gem::Version
|
|
113
|
+
version: '0'
|
|
114
|
+
requirements: []
|
|
115
|
+
rubyforge_project:
|
|
116
|
+
rubygems_version: 2.4.1
|
|
117
|
+
signing_key:
|
|
118
|
+
specification_version: 4
|
|
119
|
+
summary: Browse Hackernews via CLI.
|
|
120
|
+
test_files:
|
|
121
|
+
- spec/fixtures/page.html
|
|
122
|
+
- spec/hckr/json_builder_spec.rb
|
|
123
|
+
- spec/hckr/scraper_spec.rb
|
|
124
|
+
- spec/spec_helper.rb
|