zh / turl
- Source
- Commits
- Network (1)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Tree:
c56dad1
turl / turl.rb
| b4ea6350 » | zh | 2008-05-28 | 1 | #!/usr/bin/env ruby | |
| 2 | |||||
| 3 | require 'rubygems' | ||||
| 4 | require 'sequel' | ||||
| 5 | require 'validatable' | ||||
| 6 | require 'ramaze' | ||||
| 7 | |||||
| 36877a00 » | zh | 2008-06-13 | 8 | DB_FILE = __DIR__/'turl.db' | |
| 9 | DB = Sequel.connect("sqlite://#{DB_FILE}") | ||||
| b4ea6350 » | zh | 2008-05-28 | 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 | 42 | return '' unless t && t.valid? | |
| b4ea6350 » | zh | 2008-05-28 | 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 | 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 | 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 | 91 | def index turl=nil, *params | |
| b4ea6350 » | zh | 2008-05-28 | 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 | 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 | 108 | def _api | |
| c7cddff7 » | zh | 2008-05-28 | 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 | 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 | 137 | ||
| b4ea6350 » | zh | 2008-05-28 | 138 | if __FILE__ == $0 | |
| 7c1d4625 » | zh | 2008-11-20 | 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 | 146 | end | |

