2009年6月17日水曜日

Sinatraでアップローダー

Rubyスクリプト1つで書けるところが面白い。

app.rb
#!ruby
require 'rubygems'
require 'sinatra'
require 'sinatra/authorization'
require 'erb'
require 'fileutils'

helpers do
def authorization_realm; 'Private Zone'; end

def authorize(login, password)
login == 'id' && password == 'pw'
end
end

module Uploader
attr_reader :upload_path, :upload_dir
def initialize
@upload_path = 'files'
@upload_dir = File.join(Sinatra::Application.public, @upload_path)
end

def files
Dir.entries(upload_dir).select do |x|
!File.directory?(x)
end
end

def floor3(x)
(x * 1000).floor / 1000.0
end

def file_size(x)
s = File.stat(File.join(upload_dir, x)).size
case
when 1024 * 1024 < s
"#{floor3(s/(1024.0 * 1024.0))} M"
when 1024 < s
"#{floor3(s/1024.0)} K"
else
"#{s} bytes"
end
end
end

helpers Uploader

get '/' do
login_required
erb :index
end

post '/upload' do
if params[:file]
save_file = File.join(upload_dir, File.basename(params[:file][:filename]))
File.open(save_file, 'wb'){|f| f.write(params[:file][:tempfile].read)}
end
redirect '/'
end

get '/remove' do
if params[:file]
FileUtils.rm(File.join(upload_dir, File.basename(params[:file]))) rescue nil
end
redirect '/'
end

get '/logout' do
redirect '/' unless Rack::Auth::Basic::Request.new(request.env).provided?
response["WWW-Authenticate"] = %(Basic realm="#{authorization_realm}")
halt 401, 'Authorization Required'
end

get '*' do
redirect '/'
end

__END__

@@ index
<html>
<head>
<title>K</title>
</head>
<body>
<a href="/logout">logout</a>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="file"><input type="submit" value="upload">
</form><%
files.sort.each do |x|
%><a href="<%=escape_html(File.join(upload_path, x))%>"><%
%><%=escape_html(x)%></a> (<%=file_size(x)%>)<%
%> <a href="/remove?file=<%=escape(x)%>">remove</a><br><%
end
%></body>
</html>

0 件のコメント:

コメントを投稿