zh / turl

TinyURL service in Ramaze

This URL has Read+Write access

turl / turl.rb
b4ea6350 » zh 2008-05-28 initial import 1 #!/usr/bin/env ruby
2
3 require 'rubygems'
4 require 'sequel'
5 require 'validatable'
6 require 'ramaze'
7
36877a00 » zh 2008-06-13 sequel-2.0.1 ready 8 DB_FILE = __DIR__/'turl.db'
9 DB = Sequel.connect("sqlite://#{DB_FILE}")
b4ea6350 » zh 2008-05-28 initial import 10
11 BASE_URL = 'http://localhost:7000/'.freeze
12
13 #
14 # Model
15 #
16 class TinyURL < Sequel::Model(:turl)
17 set_schema do
18 primary_key :id
19 varchar :url
20 integer :hits
21 timestamp :created
22 index [:url], :unique => true
23 index [:created]
24 index [:hits]
25 end
26
27 include Validatable
28
29 validates do
30 presence_of :url
31 format_of :url, :with =>
32 /(^$)|(^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$)/ix,
33 :message => 'invalid URL'
34 end
35
36 after_create do
37 update_values(:created => Time.now, :hits => 1)
38 end
39
40 def self.add(uri)
41 t = TinyURL.create(:url => uri)
36877a00 » zh 2008-06-13 sequel-2.0.1 ready 42 return '' unless t && t.valid?
b4ea6350 » zh 2008-05-28 initial import 43 t.save!
44 return t.id.to_s(36)
45 end
46
47 def self.pack(uri,prefix=BASE_URL)
48 return uri if uri.length < prefix.length
49 exists = TinyURL[:url => uri]
50 turl = exists ? exists.id.to_s(36) : TinyURL.add(uri)
51 # 'index' is a controller name so insert the link once more
52 turl = TinyURL.add(uri) if turl == 'index'
53 return "#{prefix}#{turl}"
54 end
55
56 def self.unpack(turl)
57 return nil unless t = TinyURL[:id => turl.to_i(36)]
58 t.update_values(:hits => t.hits.to_i + 1)
59 t.url
60 end
61
c7cddff7 » zh 2008-05-28 small API changes - :turl a... 62 def self.count(turl)
63 return 0 unless t = TinyURL[:id => turl.to_i(36)]
64 t.hits
65 end
66
b4ea6350 » zh 2008-05-28 initial import 67 end
68
69 TinyURL.create_table unless TinyURL.table_exists?
70
71 #
72 # Controller and View
73 #
74
75 class MainController < Ramaze::Controller
76
77 LOGINS = {
78 :admin => 'secret'
79 }.map{|k,v| ["#{k}:#{v}"].pack('m').strip} unless defined? LOGINS
80
81 helper :aspect
82
83 before(:_api) do
84 response['WWW-Authenticate'] = %(Basic realm="Login Required")
85 respond 'Unauthorized', 401 unless auth = request.env['HTTP_AUTHORIZATION'] and
86 LOGINS.include? auth.split.last
87 end
88
89 layout :_page
90
43e73873 » zh 2008-11-20 small fixes (logging) from ... 91 def index turl=nil, *params
b4ea6350 » zh 2008-05-28 initial import 92 if turl
93 url = TinyURL.unpack(turl)
94 redirect(url ? url : Rs())
95 end
96 ""
97 end
98
99 def _add
100 redirect(Rs()) unless request.post?
101 turl = TinyURL.pack(request[:url])
102 "Tiny URL: <a href=\"#{turl}\">#{turl}</a><br/><br/>"
103 end
104
c7cddff7 » zh 2008-05-28 small API changes - :turl a... 105 # _api?turl=http://... will return short url
106 # _ari?url=.. will restore the original url
107 # _ari?hits=.. will return the number of hits to given turl
b4ea6350 » zh 2008-05-28 initial import 108 def _api
c7cddff7 » zh 2008-05-28 small API changes - :turl a... 109 res = TinyURL.pack(request[:turl]) if request[:turl]
110 res = TinyURL.unpack(request[:url].split('/').last) if request[:url]
111 res = TinyURL.count(request[:hits].split('/').last).to_s if request[:hits]
b4ea6350 » zh 2008-05-28 initial import 112 res = '' unless res
113 respond res
114 end
115
116 def _page
117 %{
118 <html>
119 <head>
120 <title>TinyURL Service</title>
121 </head>
122 <body>
123 #@content
124 <form id="tinyurl" method="post" action="/_add">
125 <div>
126 Enter long URL:
127 <input id="url" name="url" type="text" />
128 <input type="submit" value="Pack" />
129 </div>
130 </form>
131 </body>
132 </html>
133 }
134 end
135 end
136
43e73873 » zh 2008-11-20 small fixes (logging) from ... 137
b4ea6350 » zh 2008-05-28 initial import 138 if __FILE__ == $0
7c1d4625 » zh 2008-11-20 trying mongrel, fallback to... 139 Ramaze::Log.loggers = [ Ramaze::Logger::Informer.new( File.join(__DIR__, 'turl.log'))]
140 begin
141 require 'mongrel'
142 Ramaze.start :adapter => :mongrel, :port => 7000
143 rescue LoadError
144 Ramaze.start :adapter => :webrick, :port => 7000
145 end
b4ea6350 » zh 2008-05-28 initial import 146 end