onebox 1.5.14 → 1.5.16
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 +4 -4
- data/lib/onebox/engine.rb +1 -0
- data/lib/onebox/engine/classic_google_maps_onebox.rb +34 -21
- data/lib/onebox/engine/github_blob_onebox.rb +1 -1
- data/lib/onebox/engine/google_docs_onebox.rb +50 -0
- data/lib/onebox/engine/standard_embed.rb +21 -1
- data/lib/onebox/engine/whitelisted_generic_onebox.rb +2 -2
- data/lib/onebox/version.rb +1 -1
- data/spec/lib/onebox/engine/classic_google_maps_onebox_spec.rb +38 -24
- data/spec/lib/onebox/engine/google_docs_onebox_spec.rb +67 -0
- data/templates/githubblob.mustache +2 -2
- data/templates/twitterstatus.mustache +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05960d76842fc3238a0f46a23628e0be16c1318a
|
4
|
+
data.tar.gz: 48c532235d45121bc4f3c781b52b6400db94debb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a7f575db20f96c4267882b4cb7c9ec2b2a2c2e7335897545342ad1074a7eeccdc2bf4edd087f714c759b7560571bbe9de0b8038cb9f7d34028f4f0708b29270
|
7
|
+
data.tar.gz: 0f5e9e0d2ea683fce332e4718ad4b810d5594159fedd2ccf9338c0d964fe90f9390f842c668d940570e7b7921697825486273c4b36bc4c02f1717309dcfec5aa
|
data/lib/onebox/engine.rb
CHANGED
@@ -2,46 +2,59 @@ module Onebox
|
|
2
2
|
module Engine
|
3
3
|
class ClassicGoogleMapsOnebox
|
4
4
|
include Engine
|
5
|
-
include LayoutSupport
|
6
5
|
|
7
6
|
matches_regexp /^(https?:)?\/\/((maps|www)\.google\.[\w.]{2,}|goo\.gl)\/maps?.+$/
|
8
7
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
@url
|
8
|
+
def initialize(link, cache = nil, timeout = nil)
|
9
|
+
super(link, cache, timeout)
|
10
|
+
resolve_url!
|
13
11
|
end
|
14
12
|
|
15
13
|
def to_html
|
16
|
-
"<iframe src
|
14
|
+
"<div style=\"background:transparent;position:relative;width:690px;height:400px;top:400px;margin-top:-400px;\" onClick=\"style.pointerEvents='none'\"></div> <iframe src=\"#{link}\" width=\"690px\" height=\"400px\" frameborder=\"0\" style=\"border:0\"></iframe>"
|
15
|
+
end
|
16
|
+
|
17
|
+
def placeholder_html
|
18
|
+
return to_html unless @placeholder
|
19
|
+
"<img src=\"http://maps.googleapis.com/maps/api/staticmap?maptype=roadmap&size=690x400&sensor=false&#{@placeholder}\" width=\"690\" height=\"400\"/>"
|
17
20
|
end
|
18
21
|
|
19
22
|
private
|
20
23
|
|
24
|
+
def resolve_url!
|
25
|
+
@url = follow_redirect(@url) if @url.include?("//goo.gl/maps")
|
26
|
+
if m = @url.match(/@([-.\d]+,[-.\d]+),(\d+)z/)
|
27
|
+
@placeholder = "center=#{m[1]}&zoom=#{m[2]}"
|
28
|
+
end
|
29
|
+
|
30
|
+
@url = follow_redirect(@url) if @url.include?("www.google")
|
31
|
+
query = Hash[*URI(@url).query.split("&").map{|a|a.split("=")}.flatten]
|
32
|
+
@url += "&ll=#{query["sll"]}" if !query["ll"]
|
33
|
+
@url += "&spn=#{query["sspn"]}" if !query["spn"]
|
34
|
+
if !@placeholder
|
35
|
+
angle = (query["spn"] || query["sspn"]).split(",").first.to_f
|
36
|
+
zoom = (Math.log(690.0 * 360.0 / angle / 256.0) / Math.log(2)).round
|
37
|
+
@placeholder = "center=#{query["ll"] || query["sll"]}&zoom=#{zoom}"
|
38
|
+
end
|
39
|
+
|
40
|
+
@url = (@url =~ /output=classic/) ?
|
41
|
+
@url.sub('output=classic', 'output=embed') :
|
42
|
+
@url + '&output=embed'
|
43
|
+
end
|
44
|
+
|
21
45
|
def data
|
22
46
|
{link: url, title: url}
|
23
47
|
end
|
24
48
|
|
25
|
-
def
|
26
|
-
uri = URI(
|
49
|
+
def follow_redirect(link)
|
50
|
+
uri = URI(link)
|
27
51
|
http = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https')
|
28
52
|
http.open_timeout = timeout
|
29
53
|
http.read_timeout = timeout
|
30
54
|
response = http.head(uri.path)
|
31
|
-
response["Location"]
|
32
|
-
rescue
|
33
|
-
@url
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_long_url
|
37
|
-
uri = URI(@url)
|
38
|
-
http = Net::HTTP.start(uri.host, uri.port)
|
39
|
-
http.open_timeout = timeout
|
40
|
-
http.read_timeout = timeout
|
41
|
-
response = http.head(uri.path)
|
42
|
-
response["Location"] if response.code == "301"
|
55
|
+
response["Location"] if %(301 302).include?(response.code)
|
43
56
|
rescue
|
44
|
-
|
57
|
+
link
|
45
58
|
end
|
46
59
|
|
47
60
|
end
|
@@ -199,7 +199,7 @@ module Onebox
|
|
199
199
|
# as *side effects* of the `raw` method! They must all appear
|
200
200
|
# AFTER the call to `raw`! Don't get bitten by this like I did!
|
201
201
|
content: raw,
|
202
|
-
lang: @lang,
|
202
|
+
lang: "lang-#{@lang}",
|
203
203
|
lines: @selected_lines_array ,
|
204
204
|
has_lines: !@selected_lines_array.nil?,
|
205
205
|
selected_one_liner: @selected_one_liner,
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Onebox
|
2
|
+
module Engine
|
3
|
+
class GoogleDocsOnebox
|
4
|
+
include Engine
|
5
|
+
|
6
|
+
def self.supported_endpoints
|
7
|
+
%w(spreadsheets document forms presentation)
|
8
|
+
end
|
9
|
+
|
10
|
+
matches_regexp /^(https?:)?\/\/(docs\.google\.com)\/(?<endpoint>(#{supported_endpoints.join('|')}))\/d\/((?<key>[\w-]*)).+$/
|
11
|
+
|
12
|
+
def to_html
|
13
|
+
if document?
|
14
|
+
"<iframe class='gdocs-onebox document-onebox' src='https://docs.google.com/document/d/#{key}/pub?embedded=true' style='border: 0' width='800' height='600' frameborder='0' scrolling='yes' ></iframe>"
|
15
|
+
elsif spreadsheet?
|
16
|
+
"<iframe class='gdocs-onebox spreadsheet-onebox' src='https://docs.google.com/spreadsheet/ccc?key=#{key}&usp=sharing&rm=minimal' style='border: 0' width='800' height='600' frameborder='0' scrolling='yes' ></iframe>"
|
17
|
+
elsif presentation?
|
18
|
+
"<iframe class='gdocs-onebox presentation-onebox' src='https://docs.google.com/presentation/d/#{key}/embed?start=false&loop=false&delayms=3000' frameborder='0' width='960' height='749' allowfullscreen='true' mozallowfullscreen='true' webkitallowfullscreen='true'></iframe>"
|
19
|
+
elsif forms?
|
20
|
+
"<iframe class='gdocs-onebox forms-onebox' src='https://docs.google.com/forms/d/#{key}/viewform?embedded=true' width='760' height='500' frameborder='0' marginheight='0' marginwidth='0' scrolling='yes'>Loading...</iframe>"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def spreadsheet?
|
26
|
+
match[:endpoint] == 'spreadsheets'
|
27
|
+
end
|
28
|
+
|
29
|
+
def document?
|
30
|
+
match[:endpoint] == 'document'
|
31
|
+
end
|
32
|
+
|
33
|
+
def presentation?
|
34
|
+
match[:endpoint] == 'presentation'
|
35
|
+
end
|
36
|
+
|
37
|
+
def forms?
|
38
|
+
match[:endpoint] == 'forms'
|
39
|
+
end
|
40
|
+
|
41
|
+
def key
|
42
|
+
match[:key]
|
43
|
+
end
|
44
|
+
|
45
|
+
def match
|
46
|
+
@match ||= @url.match(@@matcher)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -6,12 +6,25 @@ module Onebox
|
|
6
6
|
@@oembed_providers ||= {}
|
7
7
|
end
|
8
8
|
|
9
|
+
def self.opengraph_providers
|
10
|
+
@@opengraph_providers ||= Array.new
|
11
|
+
end
|
12
|
+
|
9
13
|
def self.add_oembed_provider(regexp, endpoint)
|
10
14
|
oembed_providers[regexp] = endpoint
|
11
15
|
end
|
12
16
|
|
17
|
+
def self.add_opengraph_provider(regexp)
|
18
|
+
opengraph_providers.push(regexp)
|
19
|
+
end
|
20
|
+
|
13
21
|
# Some oembed providers (like meetup.com) don't provide links to themselves
|
14
22
|
add_oembed_provider /www\.meetup\.com\//, 'http://api.meetup.com/oembed'
|
23
|
+
add_oembed_provider /www\.kickstarter\.com\//, 'https://www.kickstarter.com/services/oembed'
|
24
|
+
add_oembed_provider /www\.ted\.com\//, 'http://www.ted.com/services/v1/oembed.json'
|
25
|
+
|
26
|
+
# Sites that work better with OpenGraph
|
27
|
+
add_opengraph_provider /gfycat\.com\//
|
15
28
|
|
16
29
|
def raw
|
17
30
|
return @raw if @raw
|
@@ -26,7 +39,14 @@ module Onebox
|
|
26
39
|
response = Onebox::Helpers.fetch_response(url)
|
27
40
|
html_doc = Nokogiri::HTML(response.body)
|
28
41
|
|
29
|
-
|
42
|
+
StandardEmbed.opengraph_providers.each do |regexp|
|
43
|
+
if url =~ regexp
|
44
|
+
@raw = parse_open_graph(html_doc, url)
|
45
|
+
return @raw if @raw
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Determine if we should use oEmbed or OpenGraph (prefers oEmbed)
|
30
50
|
oembed_alternate = html_doc.at("//link[@type='application/json+oembed']") || html_doc.at("//link[@type='text/json+oembed']")
|
31
51
|
fetch_oembed_raw(oembed_alternate)
|
32
52
|
|
@@ -131,7 +131,7 @@ module Onebox
|
|
131
131
|
# include the entire page HTML. However for some providers like Imgur it allows us
|
132
132
|
# to return gifv and galleries.
|
133
133
|
def self.default_html_providers
|
134
|
-
['Imgur', 'Meetup'
|
134
|
+
['Imgur', 'Meetup']
|
135
135
|
end
|
136
136
|
|
137
137
|
def self.html_providers
|
@@ -180,7 +180,7 @@ module Onebox
|
|
180
180
|
|
181
181
|
# Generates the HTML for the embedded content
|
182
182
|
def photo_type?
|
183
|
-
data[:type] =~ /photo/ || data[:type] =~ /image/
|
183
|
+
( (data[:type] =~ /photo/ || data[:type] =~ /image/) && data[:type] !~ /photostream/ )
|
184
184
|
end
|
185
185
|
|
186
186
|
def article_type?
|
data/lib/onebox/version.rb
CHANGED
@@ -1,38 +1,52 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Onebox::Engine::ClassicGoogleMapsOnebox do
|
4
|
-
describe 'long form url' do
|
5
|
-
before do
|
6
|
-
@link = "https://maps.google.ca/maps?q=Eiffel+Tower,+Avenue+Anatole+France,+Paris,+France&hl=en&sll=43.656878,-79.32085&sspn=0.932941,1.50238&oq=eiffel+&t=m&z=17&iwloc=A"
|
7
|
-
end
|
8
4
|
|
9
|
-
|
10
|
-
|
5
|
+
URLS = {
|
6
|
+
short: "https://goo.gl/maps/rEG3D",
|
7
|
+
long: "https://www.google.de/maps/place/Statue+of+Liberty+National+Monument/@40.689249,-74.0445,17z/data=!3m1!4b1!4m2!3m1!1s0x89c25090129c363d:0x40c6a5770d25022b",
|
8
|
+
canonical: "https://maps.google.de/maps?sll=40.689249,-74.0445&sspn=0.0062479,0.0109864&cid=4667599994556318251&q=Statue+of+Liberty+National+Monument&output=classic&dg=ntvb",
|
9
|
+
embed: "https://maps.google.de/maps?sll=40.689249,-74.0445&sspn=0.0062479,0.0109864&cid=4667599994556318251&q=Statue+of+Liberty+National+Monument&output=embed&dg=ntvb&ll=40.689249,-74.0445&spn=0.0062479,0.0109864"
|
10
|
+
}
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
12
|
+
before(:all) do
|
13
|
+
FakeWeb.register_uri(:head, URLS[:short], response: "HTTP/1.1 302 Found\nLocation: #{URLS[:long]}\n\n")
|
14
|
+
FakeWeb.register_uri(:head, URLS[:long], response: "HTTP/1.1 301 Moved Permanently\nLocation: #{URLS[:canonical]}\n\n")
|
17
15
|
end
|
18
16
|
|
19
|
-
|
20
|
-
let(:long_url) { "https://maps.google.ca/maps?q=Brooklyn+Bridge,+Brooklyn,+NY,+United+States&hl=en&sll=43.656878,-79.32085&sspn=0.932941,1.50238&oq=brooklyn+bridge&t=m&z=17&iwloc=A" }
|
17
|
+
subject { described_class.new(link) }
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
expect(onebox.url).to eq(long_url)
|
26
|
-
end
|
19
|
+
it_behaves_like "an engine" do
|
20
|
+
let(:link) { URLS[:canonical] }
|
21
|
+
let(:data) { Onebox::Helpers.symbolize_keys(subject.send(:data)) }
|
27
22
|
end
|
28
23
|
|
29
|
-
|
30
|
-
let(:
|
24
|
+
shared_examples "embeddable" do |kind|
|
25
|
+
let(:link) { URLS[kind] }
|
26
|
+
|
27
|
+
it "resolves url correctly" do
|
28
|
+
subject.url.should == URLS[:embed]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "produces an iframe" do
|
32
|
+
subject.to_html.should include("iframe", "output=embed")
|
33
|
+
end
|
31
34
|
|
32
|
-
it "
|
33
|
-
|
34
|
-
onebox.expects(:get_canonical_url).once.returns(embed_url)
|
35
|
-
expect(onebox.url).to eq(embed_url)
|
35
|
+
it "produces a placeholder image" do
|
36
|
+
subject.placeholder_html.should include("img")
|
36
37
|
end
|
37
38
|
end
|
39
|
+
|
40
|
+
context "canonical url" do
|
41
|
+
it_should_behave_like "embeddable", :canonical
|
42
|
+
end
|
43
|
+
|
44
|
+
context "long url" do
|
45
|
+
it_should_behave_like "embeddable", :long
|
46
|
+
end
|
47
|
+
|
48
|
+
context "short url" do
|
49
|
+
it_should_behave_like "embeddable", :short
|
50
|
+
end
|
51
|
+
|
38
52
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Onebox::Engine::GoogleDocsOnebox do
|
4
|
+
context "Spreadsheets" do
|
5
|
+
let(:matcher) { described_class.new("https://docs.google.com/spreadsheets/d/SHEET_KEY/pubhtml") }
|
6
|
+
|
7
|
+
it "should have spreadsheet class in html" do
|
8
|
+
expect(matcher.to_html).to include "spreadsheet-onebox"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be a spreadsheet" do
|
12
|
+
expect(matcher.send(:spreadsheet?)).to be true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "Should detect key" do
|
16
|
+
expect(matcher.send(:key)).to eq 'SHEET_KEY'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Documents" do
|
21
|
+
let(:matcher) { described_class.new("https://docs.google.com/document/d/DOC_KEY/pub") }
|
22
|
+
|
23
|
+
it "should have document class in html" do
|
24
|
+
expect(matcher.to_html).to include "document-onebox"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be a document" do
|
28
|
+
expect(matcher.send(:document?)).to be true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "Should detect key" do
|
32
|
+
expect(matcher.send(:key)).to eq 'DOC_KEY'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "Presentaions" do
|
37
|
+
let(:matcher) { described_class.new("https://docs.google.com/presentation/d/PRESENTATION_KEY/pub") }
|
38
|
+
|
39
|
+
it "should have presentation class in html" do
|
40
|
+
expect(matcher.to_html).to include "presentation-onebox"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be a presentation" do
|
44
|
+
expect(matcher.send(:presentation?)).to be true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "Should detect key" do
|
48
|
+
expect(matcher.send(:key)).to eq 'PRESENTATION_KEY'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "Forms" do
|
53
|
+
let(:matcher) { described_class.new("https://docs.google.com/forms/d/FORMS_KEY/viewform") }
|
54
|
+
|
55
|
+
it "should have forms class in html" do
|
56
|
+
expect(matcher.to_html).to include "forms-onebox"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be a form" do
|
60
|
+
expect(matcher.send(:forms?)).to be true
|
61
|
+
end
|
62
|
+
|
63
|
+
it "Should detect key" do
|
64
|
+
expect(matcher.send(:key)).to eq 'FORMS_KEY'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<pre><code class='{{lang}}'>{{content}}</code></pre>
|
4
4
|
{{/has_lines}}
|
5
5
|
{{#has_lines}}
|
6
|
-
{{! This is a template comment | Sample rules for this box
|
6
|
+
{{! This is a template comment | Sample rules for this box
|
7
7
|
<style>
|
8
8
|
pre.onebox code ol{
|
9
9
|
margin-left:0px;
|
@@ -34,4 +34,4 @@ pre.onebox code li.selected{
|
|
34
34
|
|
35
35
|
{{#truncated}}
|
36
36
|
This file has been truncated. <a href="{{link}}" target="_blank">show original</a>
|
37
|
-
{{/truncated}}
|
37
|
+
{{/truncated}}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onebox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joanna Zeta
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-04-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: multi_json
|
@@ -295,6 +295,7 @@ files:
|
|
295
295
|
- lib/onebox/engine/github_issue_onebox.rb
|
296
296
|
- lib/onebox/engine/github_pullrequest_onebox.rb
|
297
297
|
- lib/onebox/engine/google_calendar_onebox.rb
|
298
|
+
- lib/onebox/engine/google_docs_onebox.rb
|
298
299
|
- lib/onebox/engine/google_play_app_onebox.rb
|
299
300
|
- lib/onebox/engine/html.rb
|
300
301
|
- lib/onebox/engine/image_onebox.rb
|
@@ -348,6 +349,7 @@ files:
|
|
348
349
|
- spec/lib/onebox/engine/github_commit_onebox_spec.rb
|
349
350
|
- spec/lib/onebox/engine/github_gist_onebox_spec.rb
|
350
351
|
- spec/lib/onebox/engine/github_pullrequest_onebox_spec.rb
|
352
|
+
- spec/lib/onebox/engine/google_docs_onebox_spec.rb
|
351
353
|
- spec/lib/onebox/engine/google_play_app_onebox_spec.rb
|
352
354
|
- spec/lib/onebox/engine/html_spec.rb
|
353
355
|
- spec/lib/onebox/engine/image_onebox_spec.rb
|
@@ -407,7 +409,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
407
409
|
version: '0'
|
408
410
|
requirements: []
|
409
411
|
rubyforge_project:
|
410
|
-
rubygems_version: 2.
|
412
|
+
rubygems_version: 2.2.2
|
411
413
|
signing_key:
|
412
414
|
specification_version: 4
|
413
415
|
summary: A gem for turning URLs into previews.
|
@@ -441,6 +443,7 @@ test_files:
|
|
441
443
|
- spec/lib/onebox/engine/github_commit_onebox_spec.rb
|
442
444
|
- spec/lib/onebox/engine/github_gist_onebox_spec.rb
|
443
445
|
- spec/lib/onebox/engine/github_pullrequest_onebox_spec.rb
|
446
|
+
- spec/lib/onebox/engine/google_docs_onebox_spec.rb
|
444
447
|
- spec/lib/onebox/engine/google_play_app_onebox_spec.rb
|
445
448
|
- spec/lib/onebox/engine/html_spec.rb
|
446
449
|
- spec/lib/onebox/engine/image_onebox_spec.rb
|
@@ -460,4 +463,3 @@ test_files:
|
|
460
463
|
- spec/lib/onebox_spec.rb
|
461
464
|
- spec/spec_helper.rb
|
462
465
|
- spec/support/html_spec_helper.rb
|
463
|
-
has_rdoc:
|