Skip to content

Instantly share code, notes, and snippets.

@song940
Created October 11, 2013 09:42
Show Gist options
  • Save song940/6932196 to your computer and use it in GitHub Desktop.
Save song940/6932196 to your computer and use it in GitHub Desktop.
网址压缩
require 'rubygems'
require 'sinatra'
require 'dm-core'
require 'dm-timestamps'
require 'dm-migrations'
require 'dm-serializer'
require 'json'
require 'net/http'
require 'openssl'
configure do
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/default.db")
class URLInfo
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
property :url, String, :required => true
property :hit, Integer, :default => 0
property :created_at, DateTime
property :updated_at, DateTime
end
# automatically migrate database if needed
DataMapper.auto_migrate!
end
def keygen_sub
arr = []
[0 .. 9, 'a' .. 'z', 'A' .. 'Z'].each do |range|
arr += range.to_a
end
word = ""
5.times { word += arr[ rand( arr.size ) ].to_s }
word
end
def keygen
key = keygen_sub
URLInfo.all(:name => key).size == 0 ? key : keygen
end
def fetch_title(url)
uri = URI(url)
http = Net::HTTP.new(uri.host,uri.port)
http.verify_mode=OpenSSL::SSL::VERIFY_NONE
http.use_ssl=uri.scheme == 'https'
res = http.get(uri.path.empty? ? '/' : uri.path)
if res.is_a? Net::HTTPRedirection
return fetch_title res['Location']
end
charset=res.type_params['charset'] || 'utf-8'
html = res.body.encode('utf-8',charset)
title_re = /<title\b[^>]*>([^<]+)<\/title>/
return title_re.match(html) && title_re.match(html)[1] || ''
end
before do
headers "Content-Type" => "text/html; charset=utf8"
end
get '/' do
erb :index
end
get '/:name' do
info = URLInfo.first(:name => params[:name])
info.update(:hit => info.hit + 1) unless info.nil?
redirect info.url unless info.nil?
end
get '/info/:name' do
@info = URLInfo.first(:name => params[:name])
@title = fetch_title @info.url
#@info[:title] = title
erb :info
end
#
#URL
#Alias
post '/api/short_url' do
info = URLInfo.first_or_create({:url => params[:url]},{
:name => (params[:alias].empty? || !URLInfo.first(:name => params[:alias]).nil?) ? keygen : params[:alias],
:url => params[:url]
})
info.to_json
#{ :id => info.id, }.to_json
end
enable :inline_templates
__END__
@@ layout
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" ></meta>
<title >GO! - URL Shorter</title>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="//static.lsong.org/css/bootstrap.css">
<link rel="stylesheet" href="//static.lsong.org/css/bootstrap-responsive.css">
<script src="//static.lsong.org/js/jquery.js" ></script>
<script >
(function($){
$(function($){
var tinyUrl = function(url, alias){
$('.result').hide();
$('.show-result').hide();
$.ajax({
url: '/api/short_url',
data: { 'url' : url, 'alias': alias},
type: 'POST',
dataType: 'json',
error:function(err){
$('.alert').removeClass('alert-success alert-error').addClass('alert-error').text('Error').show();
$('.show-result').show();
},
success:function(data){
$('.txt-tiny-url').val(location.href + data.name);
$('.btn-view').attr('href',location.href + "info/" + data.name);
$('.btn-open').attr('href',location.href + data.name);
$('.alert').removeClass('alert-success alert-error').addClass('alert-success').text('Success').show();
$('.show-result').show('fast');
$('.result').show();
}
});
};
$('.form-short').submit(function(ev){
ev.preventDefault();
var url = $('.txt-long-url').val();
var alias = $('.txt-alias').val();
tinyUrl(url,alias);
});
$('.txt-tiny-url').on('click',function(ev){
ev.preventDefault();
this.select();
});
$('.btn-open').click(function(ev){
ev.preventDefault();
window.open(this.href);
});
});
})(jQuery);
</script>
<style>
html,body{
font-family: 'Open Sans'
}
.footer{
height: 60px;
margin-top: 60px;
background-color: #f5f5f5;
}
.container{
width: auto;
max-width: 680px;
}
.footer p {
margin: 20px 0;
}
input[readonly]{
background-color: #fff;
}
</style>
</head>
<body>
<div class="container" >
<div class="header page-header" >
<ul class="nav nav-pills pull-right" >
<li><a href="//lsong.org" >Home</a></li>
</ul>
<h1><a href="/">Go! </a></h1>
</div>
<div class="content" >
<%= yield %>
</div>
<div class="footer" >
<p class="muted" >&copy;LSONG.ORG</p>
</div>
</div>
</body>
</html>
@@ index
<h2>Short URL</h2>
<form class="form-short" >
<fieldset>
<div class="controls controls-row" >
<input type="url" class="input span6 txt-long-url" placeholder="Enter another long URL to make tiny" required />
<input type='text' value="" class="span1 txt-alias" placeholder="Alias" />
</div>
<button class="btn btn-large btn-block btn-primary" type="submit">Go!</button>
</fieldset>
</form>
<div class="show-result hide" >
<div class="alert" >Success</div>
<div class="result" >
<div class="input-prepend input-append" >
<span class="add-on" >URL:</span>
<input class="input txt-tiny-url" readonly="readonly" type="text" />
<a class="btn btn-mini btn-share add-on" >Share</a>
<a class="btn btn-mini btn-view add-on" >Info</a>
<a class="btn btn-mini btn-open add-on" >Continue</a>
</div>
</div>
</div>
@@ info
<span class="badge badge-success pull-right" ><%= @info.hit %></span>
<h2>Preview</h2>
<div class="well">
<h3><%= @title %></h3>
<a href=<%= @info.url %> ><%= @info.url %></a>
<a href=<%= @info.url %> class="btn btn-primary btn-mini" >Continue</a>
</div>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'tinyurl'; // required: replace example with your forum shortname
var disqus_identifier = '<%= @info.name %>';
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment