Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
この記事に対してトラックバックを送信する(FC2ブログユーザー)
http://kovayashi.blog120.fc2.com/tb.php/79-13459e74

-件のトラックバック

-件のコメント

コメントの投稿

投稿フォーム
投稿した内容は管理者にだけ閲覧出来ます

シンプルなアップローダの作り方

ruby+sqlite3で、シンプルなアップローダを作ってみよう!!

?ファイルをアップロードするhtmlフォームを返すcgiを作ってみる。

#!/usr/local/bin/ruby
require 'cgi'
cgi=CGI.new('html3')
cgi.out('status'=>'OK'){DATA.read}
__END__
<html>
<body>
<form enctype="multipart/form-data">
<input type="file" name="data" size="60">
<input type="submit" value="Upload"/>
</form>
</body>



?フォームのボタンが押されたら、URL(先ずは固定)を出力するように改造する。

#!/usr/local/bin/ruby
require 'cgi'
←?はここに記述
CGINAME= 'http://' + ENV['HTTP_HOST'] + ENV['SCRIPT_NAME']
cgi=CGI.new('html3')
if cgi.has_key?('data') then
cgi.out('status'=>'OK'){CGINAME + '?id=' + 'xxxxxx'} ?はこの行を改修
←?はここに記述
else
cgi.out('status'=>'OK'){DATA.read.sub(/XXXXXX/,'"'+ CGINAME + '"')}
end
__END__
<html>
<body>
<form method="post" action=XXXXXX enctype="multipart/form-data">
<input type="file" name="data" size="60">
<input type="submit" value="Upload"/>
</form>
</body>
</html>


?ファイルをDBに突っ込む前準備として、DBが無い場合(初っ端)はDBも作る処理を追記する。

require 'rubygems'
require 'amalgalite'

DBFILE='./up.db'
sw=File.exist?(DBFILE)
db=Amalgalite::Database.new(DBFILE)
unless sw then
sql=<<EOS
create table table01 (
name text,
val blob
);
EOS
db.execute(sql)
end


amalgaliteをインストールする。(たぶんsqlite3のインストールは不要)

>gem install amalgalite


?アップロードされたファイルをDBに突っ込み、urlを返す様にに改造する。

require 'kconv'

name=cgi['data'].original_filename.toeuc.gsub(/.*\\/,'')
blob_column = db.schema.tables['table01'].columns['val']
rowid=nil
db.transaction do |t|
t.execute('replace into table01 (name, val) values(?, ?)',name,Amalgalite::Blob.new(
:io=>cgi['data'],
:column=>blob_column
))
rowid = t.execute('select count(rowid) from table01')
end
cgi.out('status'=>'OK'){
CGINAME + '?id=' + rowid.to_s
}


?cgiのクエリーにidが有ったら、DBからファイルを引っこ抜き、レスポンスするように改造する。

elsif cgi.has_key?('id') then

BUFFER_SIZE=1024*1024*20

name=db.execute('select name from table01 where rowid=?', cgi['id'])[0][0]

header={
'pragma'=>'no-cache',
'cache-control'=>'no-cache,must-revalidate',
'Transfer-Encoding'=>'chunked',
'Content-type'=>'application/octet-stream',
'Content-Disposition'=>'attachment; filename="' + name + '"'
}

STDOUT.binmode
STDOUT.print "Status: 200 OK\r\n"
header.each do |key,value|
STDOUT.print "#{key}: #{value}\r\n"
end

column = db.schema.tables['table01'].columns['val']
b=Amalgalite::SQLite3::Blob.new( column.schema.db.api,
column.db,
column.table,
column.name,
cgi['id'].to_i,
"r"
)
STDOUT.printf("\r\n%X\r\n",b.length)
while buf=b.read(BUFFER_SIZE)
STDOUT.write(buf)
end

STDOUT.print "\r\n0\r\n"


纏めると以下85ステップ

#!/usr/local/bin/ruby

require 'cgi'
require 'kconv'
require 'rubygems'
require 'amalgalite'

BUFFER_SIZE=1024*1024*20

DBFILE='./up.db'
sw=File.exist?(DBFILE)
db=Amalgalite::Database.new(DBFILE)
unless sw then
sql=<<EOS
create table table01 (
name text,
val blob
);
EOS
db.execute(sql)
end

CGINAME= 'http://' + ENV['HTTP_HOST'] + ENV['SCRIPT_NAME']
cgi=CGI.new('html3')

if cgi.has_key?('data') then
name=cgi['data'].original_filename.toeuc.gsub(/.*\\/,'')
blob_column = db.schema.tables['table01'].columns['val']
rowid=nil
db.transaction do |t|
t.execute('replace into table01 (name, val) values(?, ?)',name,Amalgalite::Blob.new(
:io=>cgi['data'],
:column=>blob_column
))
rowid = t.execute('select count(rowid) from table01')
end

cgi.out('status'=>'OK'){
CGINAME + '?id=' + rowid.to_s
}
elsif cgi.has_key?('id') then
name=db.execute('select name from table01 where rowid=?', cgi['id'])[0][0]

header={
'pragma'=>'no-cache',
'cache-control'=>'no-cache,must-revalidate',
'Transfer-Encoding'=>'chunked',
'Content-type'=>'application/octet-stream',
'Content-Disposition'=>'attachment; filename="' + name + '"'
}

STDOUT.binmode
STDOUT.print "Status: 200 OK\r\n"
header.each do |key,value|
STDOUT.print "#{key}: #{value}\r\n"
end

column = db.schema.tables['table01'].columns['val']
b=Amalgalite::SQLite3::Blob.new(column.schema.db.api,
column.db,
column.table,
column.name,
cgi['id'].to_i,
"r"
)

STDOUT.printf("\r\n%X\r\n",b.length)
while buf=b.read(BUFFER_SIZE)
STDOUT.write(buf)
end

STDOUT.print "\r\n0\r\n"

else
cgi.out('status'=>'OK'){DATA.read.sub(/XXXXXX/,'"'+ CGINAME + '"')}
end
__END__
<html>
<body>
<form method="post" action=XXXXXX enctype="multipart/form-data">
<input type="file" name="data" size="60">
<input type="submit" value="Upload"/>
</form>
</body>
</html>


たったの85ステップ!!

see also
http://kovayashi.blog120.fc2.com/blog-entry-102.html
この記事に対してトラックバックを送信する(FC2ブログユーザー)
http://kovayashi.blog120.fc2.com/tb.php/79-13459e74

0件のトラックバック

0件のコメント

コメントの投稿

投稿フォーム
投稿した内容は管理者にだけ閲覧出来ます

Appendix

プロフィール

kovayashi

Author:kovayashi
・嫌いなもの
 →好きなもの

・インストール
 →バンドル
・バックアップ
 →アップロード
・努力
 →チート

最近のトラックバック

ブログ内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。