Created
June 21, 2011 12:30
-
-
Save myobie/1037750 to your computer and use it in GitHub Desktop.
unfurler.heroku.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The Unfurler! | |
============= | |
## What is it? | |
You give it a shortened url and it looks up where it would take you. There is a | |
version running at http://unfurler.heroku.com if you want to try it out. | |
## How do I run it? | |
$ bundle install | |
$ shotgun | |
## How do I deploy it? | |
$ gem install heroku | |
$ heroku create | |
$ git push heroku master | |
$ heroku open | |
## How do I use it? | |
Navigate to http://localhost:9393/ and type in a shortend url. You can also just | |
use the address bar like so: http://localhost:9393/u/bit.ly/ieHELP | |
## API? | |
There is a json api, believe it or not. Just use /j/ instead of /u/ to get json | |
back, like so: http://localhost:9393/j/bit.ly/ieHELP | |
To do this with jQuery, this would look like: | |
$.get('http://localhost:9393/j/bit.ly/ieHELP', {}, function(data) { | |
console.log(JSON.stringify(data)) | |
}, "json") | |
or if you want to use a `script` tag and have it fire a callback, you can do: | |
<script> | |
function foo(json) { | |
alert(JSON.stringify(json)); | |
} | |
node = document.createElement('script'); | |
node.src = "http://unfurler.heroku.com/j/bit.ly/ieHELP?callback=foo"; | |
document.body.appendChild(node); // this loads and runs the script | |
</script> | |
If you want it to run on page load, just put it in a script tag manually like so: | |
<!-- define `foo` in a script tag before this one --> | |
<script src="http://unfurler.heroku.com/j/bit.ly/ieHELP?callback=foo"></script> | |
The callback is provided to help get around XSS protections. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'sinatra' | |
require 'httparty' | |
require 'haml' | |
require 'json' | |
set :haml, :format => :html5 | |
class Unfurler | |
attr_accessor :redirects, :protocol, :url, :response | |
def initialize new_url | |
self.url, self.redirects = new_url, [] | |
end | |
def url= new_url | |
@protocol = if proto = new_url.match(%r{^(http[s]*://)}) | |
proto[1] | |
else | |
"http://" | |
end | |
@url = new_url.gsub %r{^http[s]*://}, '' | |
end | |
def full_url | |
protocol + url | |
end | |
def head | |
HTTParty.head full_url, follow_redirects: false | |
end | |
def fetch! | |
@response = head | |
if @response.code.to_s =~ /30[12]/ | |
@redirects << response.headers['location'] | |
unfurler = self.class.new(@redirects.last).fetch! | |
@redirects.concat unfurler.redirects | |
end | |
self # return self so it's chainable | |
end | |
end | |
helpers do | |
def title new_title | |
@title = new_title | |
end | |
def partial name, locals = {} | |
haml name.to_sym, :layout => false, :locals => locals | |
end | |
end | |
get '/' do | |
title 'Home' | |
haml :index | |
end | |
get '/u/*', :provides => 'html' do | |
expires 604800, :public # cache for a week | |
# :url and :splat to support js and non-js users | |
url_param = params[:url] || (params[:splat] || []).join("/") | |
throw 404 if url_param.nil? || url_param.empty? | |
@unfurler = Unfurler.new(url_param).fetch! | |
title "Unfurling #{@unfurler.url}" | |
if @unfurler.redirects.empty? | |
haml :not_a_redirect | |
else | |
haml :unfurled | |
end | |
end | |
get '/j/*' do | |
content_type :json | |
@url_to_request = params[:splat].join("/").gsub(/http:\/\//, '') | |
@url_response = Unfuler.new(@url_to_request).head | |
json = @url_response.headers.to_hash.to_json | |
unless params[:callback].nil? || params[:callback].empty? | |
json = params[:callback] + "(#{json})" | |
end | |
json | |
end | |
get '/style.css' do | |
content_type :css | |
erb :stylesheet, layout: false | |
end | |
get '/site.js' do | |
content_type :js | |
erb :javascript, layout: false | |
end | |
template :layout do | |
%q{ | |
!!! | |
%html | |
%head | |
%title= "#{@title} - Unfurler" | |
%link(rel="stylesheet" href="/style.css") | |
%link(rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKBJREFUeNpidHNzYyAFMDGQCGivgQWIAwMD5eTkJk6cCBGCc/Pz8zU0NOBKb9y4ARQEaQBKI0ugcdevXw9hfPv2DWoDfrBr1y50J+EH8HA/d+7cmzdvCGvQ1NSE+4EoG+CBgQjW69evA8no6GigX4EOAJIQw3AG65EjR4D22oABkAt0KDxkMAEj3E8iYAAMu0ePHhGIOAh4AwaDIC0BBBgAvws9sktyKQMAAAAASUVORK5CYII=") | |
%body | |
%h1 | |
%a(href="/") The Unfurler! | |
= yield | |
%script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js") | |
%script(src="/site.js") | |
} | |
end | |
template :index do | |
%q{ | |
%form#the-form(action="/u/") | |
%p | |
%label(for="url") URL to unfurl: | |
%input(name="url" id="url" placeholder="URL to unfurl" autofocus) | |
%p | |
%button(type="submit") Unfurl | |
} | |
end | |
template :unfurled do | |
%q{ | |
%p | |
You provided | |
%a(href="#{@unfurler.full_url}")= @unfurler.url | |
- @unfurler.redirects.each do |r| | |
= partial(:redirect, redirect: r) | |
} | |
end | |
template :redirect do | |
%q{ | |
which redirects to | |
%a(href="#{redirect}")= redirect | |
} | |
end | |
template :not_a_redirect do | |
%q{ | |
%p | |
You provided | |
%a(href="#{@unfurler.full_url}")= @unfurler.url | |
which doesn't redirect anywhere. | |
} | |
end | |
template :stylesheet do | |
%q[ | |
html { background: #eee; } | |
body { | |
width: 500px; | |
margin: 0 auto; | |
padding: 20px; | |
background: #fff; | |
-webkit-box-shadow: 0 1px 9px rgba(0,0,0,0.1); | |
-moz-box-shadow: 0 1px 9px rgba(0,0,0,0.1); | |
box-shadow: 0 1px 9px rgba(0,0,0,0.1); | |
font: 16px/1.6 Helvetica Neue, Arial, sans-serif; | |
color: #333; | |
} | |
h1 { text-align: center; } | |
h1, p { margin: 0 0 1em; } | |
h1 a { | |
color: #333; | |
text-decoration: none; | |
} | |
h1 a:hover { color: #000; } | |
body.loaded label { display: none; } | |
input { | |
width: 400px; | |
font: 16px/1.3 Helvetica Neue, Arial, sans-serif; | |
} | |
form p { text-align: center; } | |
] | |
end | |
template :javascript do | |
%q@ | |
document.body.className = "loaded"; | |
if (document.getElementById('the-form')) { | |
document.getElementById('the-form').onsubmit = function(event) { | |
var url = document.getElementsByTagName('input')[0].value; | |
window.location = window.location.protocol + "//" + | |
window.location.host + "/u/" + url.replace(/http:\/\//, ''); | |
return false; | |
}; | |
} | |
@ | |
end | |
run Sinatra::Application |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source :rubygems | |
gem 'sinatra' | |
gem 'httparty' | |
gem 'haml' | |
gem 'json' | |
group :development do | |
gem 'shotgun' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GEM | |
remote: http://rubygems.org/ | |
specs: | |
crack (0.1.8) | |
haml (3.1.2) | |
httparty (0.7.8) | |
crack (= 0.1.8) | |
json (1.5.3) | |
rack (1.3.0) | |
shotgun (0.9) | |
rack (>= 1.0) | |
sinatra (1.2.6) | |
rack (~> 1.1) | |
tilt (< 2.0, >= 1.2.2) | |
tilt (1.3.2) | |
PLATFORMS | |
ruby | |
DEPENDENCIES | |
haml | |
httparty | |
json | |
shotgun | |
sinatra |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment