Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 34 additions & 21 deletions lib/onebox/engine/classic_google_maps_onebox.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,59 @@ module Onebox
module Engine
class ClassicGoogleMapsOnebox
include Engine
include LayoutSupport

matches_regexp /^(https?:)?\/\/((maps|www)\.google\.[\w.]{2,}|goo\.gl)\/maps?.+$/

def url
@url = get_long_url if @url.include?("//goo.gl/maps/")
@url = get_canonical_url if @url.include?("www.google")
@url
def initialize(link, cache = nil, timeout = nil)
super(link, cache, timeout)
resolve_url!
end

def to_html
"<iframe src='#{url}&output=embed' width='690px' height='400px' frameborder='0' style='border:0'></iframe>"
"<iframe src=\"#{link}\" width=\"690px\" height=\"400px\" frameborder=\"0\" style=\"border:0\"></iframe>"
end

def placeholder_html
return to_html unless @placeholder
"<img src=\"http://maps.googleapis.com/maps/api/staticmap?maptype=roadmap&size=690x400&sensor=false&#{@placeholder}\" width=\"690\" height=\"400\"/>"
end

private

def resolve_url!
@url = follow_redirect(@url) if @url.include?("//goo.gl/maps")
if m = @url.match(/@([-.\d]+,[-.\d]+),(\d+)z/)
@placeholder = "center=#{m[1]}&zoom=#{m[2]}"
end

@url = follow_redirect(@url) if @url.include?("www.google")
query = Hash[*URI(@url).query.split("&").map{|a|a.split("=")}.flatten]
@url += "&ll=#{query["sll"]}" if !query["ll"]
@url += "&spn=#{query["sspn"]}" if !query["spn"]
if !@placeholder
angle = (query["spn"] || query["sspn"]).split(",").first.to_f
zoom = (Math.log(690.0 * 360.0 / angle / 256.0) / Math.log(2)).round
@placeholder = "center=#{query["ll"] || query["sll"]}&zoom=#{zoom}"
end

@url = (@url =~ /output=classic/) ?
@url.sub('output=classic', 'output=embed') :
@url + '&output=embed'
end

def data
{link: url, title: url}
end

def get_canonical_url
uri = URI(@url)
def follow_redirect(link)
uri = URI(link)
http = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https')
http.open_timeout = timeout
http.read_timeout = timeout
response = http.head(uri.path)
response["Location"].sub(/&?output=classic/, '') if response.code == "302"
rescue
@url
end

def get_long_url
uri = URI(@url)
http = Net::HTTP.start(uri.host, uri.port)
http.open_timeout = timeout
http.read_timeout = timeout
response = http.head(uri.path)
response["Location"] if response.code == "301"
response["Location"] if %(301 302).include?(response.code)
rescue
@url
link
end

end
Expand Down
62 changes: 38 additions & 24 deletions spec/lib/onebox/engine/classic_google_maps_onebox_spec.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
require "spec_helper"

describe Onebox::Engine::ClassicGoogleMapsOnebox do
describe 'long form url' do
before do
@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"
end

include_context "engines"
it_behaves_like "an engine"
URLS = {
short: "https://goo.gl/maps/rEG3D",
long: "https://www.google.de/maps/place/Statue+of+Liberty+National+Monument/@40.689249,-74.0445,17z/data=!3m1!4b1!4m2!3m1!1s0x89c25090129c363d:0x40c6a5770d25022b",
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",
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"
}

describe "#to_html" do
it "embeds the iframe to display the map" do
expect(html).to include("iframe")
end
end
before(:all) do
FakeWeb.register_uri(:head, URLS[:short], response: "HTTP/1.1 302 Found\nLocation: #{URLS[:long]}\n\n")
FakeWeb.register_uri(:head, URLS[:long], response: "HTTP/1.1 301 Moved Permanently\nLocation: #{URLS[:canonical]}\n\n")
end

describe 'short form url' do
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" }
subject { described_class.new(link) }

it "retrieves the long form url" do
onebox = described_class.new("http://goo.gl/maps/XffUa")
onebox.expects(:get_long_url).once.returns(long_url)
expect(onebox.url).to eq(long_url)
end
it_behaves_like "an engine" do
let(:link) { URLS[:canonical] }
let(:data) { Onebox::Helpers.symbolize_keys(subject.send(:data)) }
end

describe 'www form url' do
let(:embed_url) { "https://maps.google.de/maps?t=h&ll=48.398499,9.992333&spn=0.0038338,0.0056322&dg=ntvb&output=embed" }
shared_examples "embeddable" do |kind|
let(:link) { URLS[kind] }

it "resolves url correctly" do
subject.url.should == URLS[:embed]
end

it "produces an iframe" do
subject.to_html.should include("iframe", "output=embed")
end

it "retrieves the canonical url" do
onebox = described_class.new("https://www.google.de/maps/@48.3932366,9.992333,663a,20y,41.43t/data=!3m1!1e3")
onebox.expects(:get_canonical_url).once.returns(embed_url)
expect(onebox.url).to eq(embed_url)
it "produces a placeholder image" do
subject.placeholder_html.should include("img")
end
end

context "canonical url" do
it_should_behave_like "embeddable", :canonical
end

context "long url" do
it_should_behave_like "embeddable", :long
end

context "short url" do
it_should_behave_like "embeddable", :short
end

end