Skip to content

Instantly share code, notes, and snippets.

@ProfAvery
Created February 9, 2012 07:09
Show Gist options
  • Save ProfAvery/1778037 to your computer and use it in GitHub Desktop.
Save ProfAvery/1778037 to your computer and use it in GitHub Desktop.
Crazy Eddie's Discount URL Shortener
#!/usr/bin/env ruby
require 'sinatra'
require 'redis'
require 'enumerator'
configure do
REDIS = Redis.new
REDIS.setnx 'next', 10 * 36 ** 3
end
helpers do
def next_key
incr = rand(10) + 1
value = REDIS.incrby 'next', incr
value.to_s(36)
end
end
before '/' do
@popular = REDIS.zrevrange 'hits', 0, 9, :with_scores => true
end
get '/' do
erb :index
end
post '/' do
@input_url = params[:input_url]
return erb :index if @input_url.empty?
base_url = "http://#{request.host_with_port}/"
if @input_url =~ %r[^#{base_url}(.*)$]
@output_url = REDIS.get 'short:' + $1
return erb :index
end
@output_url = REDIS.get 'long:' + @input_url
return erb :index unless @output_url.nil?
key = next_key
@output_url = base_url + key
REDIS.set 'short:' + key, @input_url
REDIS.setnx 'long:' + @input_url, @output_url
erb :index
end
get '/:key' do
key = params[:key]
@input_url = REDIS.get 'short:' + key
if @input_url.nil?
halt 404, '404 No such shortened URL'
end
@output_url = REDIS.get 'long:' + @input_url
link = %[<a href="#{@output_url}">#{@input_url}</a>]
REDIS.zincrby 'hits', 1, link
redirect @input_url #, 301
end
__END__
@@index
<!DOCTYPE html>
<html>
<head>
<title>Crazy Eddie's discount URL shortener</title>
</head>
<body>
<h1>Enter an URL to shorten</h1>
<p>(or a shortened URL to preview)</p>
<form method="POST">
<input type="text" name="input_url" size="50"
value="<%= @input_url %>"/>
<input type="submit" value="Go" />
</form>
<% if @output_url %>
<h2><a href="<%= @output_url %>"><%= @output_url %></a></h2>
<% end %>
<% if !@popular.empty? %>
<h3>Popular Links</h3>
<ul>
<% @popular.each_slice(2) do |link, hits| %>
<li><%= link %> (<%= hits %> <%= hits.to_i > 1? 'hits' : 'hit' %>)</li>
<% end %>
</ul>
<% end %>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment