FEATURE: Onebox for news.ycombinator.com (#15781)

This commit is contained in:
Rafael dos Santos Silva 2022-02-03 13:39:21 -03:00 committed by GitHub
parent ea37b30ab2
commit 5b5cbbfe5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 0 deletions

View File

@ -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"

View File

@ -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

View File

@ -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>

View File

@ -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"}

View File

@ -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"}

View File

@ -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