FEATURE: Onebox for news.ycombinator.com (#15781)
This commit is contained in:
parent
ea37b30ab2
commit
5b5cbbfe5c
|
@ -210,3 +210,4 @@ require_relative "engine/kaltura_onebox"
|
|||
require_relative "engine/reddit_media_onebox"
|
||||
require_relative "engine/google_drive_onebox"
|
||||
require_relative "engine/facebook_media_onebox"
|
||||
require_relative "engine/hackernews_onebox"
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Onebox
|
||||
module Engine
|
||||
class HackernewsOnebox
|
||||
include Engine
|
||||
include LayoutSupport
|
||||
include JSON
|
||||
|
||||
REGEX = /^https?:\/\/news\.ycombinator\.com\/item\?id=(?<item_id>\d+)/
|
||||
|
||||
matches_regexp(REGEX)
|
||||
|
||||
# This is their official API: https://blog.ycombinator.com/hacker-news-api/
|
||||
def url
|
||||
"https://hacker-news.firebaseio.com/v0/item/#{match[:item_id]}.json"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def match
|
||||
@match ||= @url.match(REGEX)
|
||||
end
|
||||
|
||||
def data
|
||||
return nil unless %w{story comment}.include?(raw['type'])
|
||||
|
||||
html_entities = HTMLEntities.new
|
||||
data = {
|
||||
link: @url,
|
||||
title: Onebox::Helpers.truncate(raw['title'], 80),
|
||||
favicon: 'https://news.ycombinator.com/y18.gif',
|
||||
timestamp: Time.at(raw['time']).strftime("%-l:%M %p - %-d %b %Y"),
|
||||
author: raw['by']
|
||||
}
|
||||
|
||||
data['description'] = html_entities.decode(Onebox::Helpers.truncate(raw['text'], 400)) if raw['text']
|
||||
|
||||
if raw['type'] == 'story'
|
||||
data['data_1'] = raw['score']
|
||||
data['data_2'] = raw['descendants']
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
<h3><a href="{{link}}" target="_blank" rel="noopener">{{title}}</a></h3>
|
||||
|
||||
{{#description}}
|
||||
<p>{{description}}</p>
|
||||
{{/description}}
|
||||
|
||||
|
||||
<p>
|
||||
{{#data_1}}
|
||||
<span class="label1">{{data_1}} points</span> —
|
||||
{{/data_1}}
|
||||
{{#data_2}}
|
||||
<span class="label2">{{data_2}} comments</span> —
|
||||
{{/data_2}}
|
||||
<a href="https://news.ycombinator.com/user?id={{author}}" class="author" target="_blank" rel="noopener">{{author}}</a> —
|
||||
<a href="{{link}}" class="timestamp" target="_blank" rel="noopener">{{timestamp}}</a>
|
||||
</p>
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"by":"codinghorror","id":5173615,"parent":5173013,"text":"Completely, forums are about basic human expression in paragraph form. This is an essential right and we want to give it back to the world in 100% no strings attached open source form.<p>Not that there aren't other forum choices, of course there are, but VERY few are 100% open source and even fewer are ones I <i>want</i> to use.","time":1360102194,"type":"comment"}
|
|
@ -0,0 +1 @@
|
|||
{"by":"sosuke","descendants":270,"id":5172905,"kids":[5173142,5173462,5173017,5173011,5173162,5173096,5173389,5173293,5173674,5173185,5173184,5173102,5176942,5173013,5173470,5173134,5174761,5173633,5173075,5173367,5173441,5172994,5172963,5173100,5173129,5173922,5173532,5175377,5173063,5173118,5174902,5173062,5173188,5173217,5174393,5173283,5173595,5175282,5174673,5173220,5173987,5174254,5174114,5173433,5172970,5174863,5173152,5173268,5174226,5173925,5174224,5173045,5174240,5173307,5174395,5175680,5174795,5174098,5175464,5175574,5173095,5179521,5173072,5173511,5175643,5176315,5173012,5173054,5173512,5175604,5173042,5173608,5172961,5177654,5178409,5174238,5173099,5174201,5173081,5175087,5174260,5173820,5174730],"score":727,"time":1360094559,"title":"Civilized Discourse Construction Kit","type":"story","url":"http://www.codinghorror.com/blog/2013/02/civilized-discourse-construction-kit.html"}
|
|
@ -0,0 +1,57 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Onebox::Engine::HackernewsOnebox do
|
||||
context "When oneboxing a comment" do
|
||||
let(:link) { "https://news.ycombinator.com/item?id=30181167" }
|
||||
let(:api_link) { "https://hacker-news.firebaseio.com/v0/item/30181167.json" }
|
||||
let(:html) { described_class.new(link).to_html }
|
||||
|
||||
before do
|
||||
stub_request(:get, api_link).to_return(status: 200, body: onebox_response("hackernews_comment"))
|
||||
end
|
||||
|
||||
it "has the comments first words" do
|
||||
expect(html).to include("Completely, forums are about basic human expression in paragraph form.")
|
||||
end
|
||||
|
||||
it "has author username" do
|
||||
expect(html).to include("codinghorror")
|
||||
end
|
||||
|
||||
it "has the permalink to the comic" do
|
||||
expect(html).to include(link)
|
||||
end
|
||||
|
||||
it "has the item date" do
|
||||
expect(html).to include("2013")
|
||||
end
|
||||
end
|
||||
|
||||
context "When oneboxing a story" do
|
||||
let(:link) { "https://news.ycombinator.com/item?id=5172905" }
|
||||
let(:api_link) { "https://hacker-news.firebaseio.com/v0/item/5172905.json" }
|
||||
let(:html) { described_class.new(link).to_html }
|
||||
|
||||
before do
|
||||
stub_request(:get, api_link).to_return(status: 200, body: onebox_response("hackernews_story"))
|
||||
end
|
||||
|
||||
it "has story title" do
|
||||
expect(html).to include("Civilized Discourse Construction Kit")
|
||||
end
|
||||
|
||||
it "has author username" do
|
||||
expect(html).to include("sosuke")
|
||||
end
|
||||
|
||||
it "has the permalink to the comic" do
|
||||
expect(html).to include(link)
|
||||
end
|
||||
|
||||
it "has the item date" do
|
||||
expect(html).to include("2013")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue