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/reddit_media_onebox"
|
||||||
require_relative "engine/google_drive_onebox"
|
require_relative "engine/google_drive_onebox"
|
||||||
require_relative "engine/facebook_media_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