February 24, 2004

3時間で作る携帯向けCGI

今度、学科で見学旅行があるのですが、その日程の確認のために協力して欲しいとのことだったので、携帯から見られるサイトを急造しました。というわけでタイトルにあるとおり、いかに素早く携帯向けCGIを作るかにチャレンジしました。

結果、フルスクラッチで3時間でした。使用言語はRuby
まず、データの整理をします。受け取った確認内容のファイルが、誰がどこに宿泊するかを書かいてあるExcelのファイルだったので、これをCSV形式(カンマ区切りテキストのことです)にして、Excelから吐き出します。吐き出す方法は保存の際に『ファイルの種類』を『CSV (カンマ区切り) (*.csv)』と指定すればOK。
次に、これをCGIからハンドリングしやすくするためにPStore形式に変換します。PStoreとはRubyのライブラリに標準添付されている簡易データベースのようなもので、内部的にはHash構造になっており、扱い勝手は最高です。csv2pstore.rbスクリプトで変換しました(ソースは続きにおいておきます)。
PStoreに突っ込むとき、なお、日本の携帯の文字コードはShift-JISでWindowsと同じなので、文字コードは気にせず、そのままファイルにぶち込みます。使い方は

$ ./csv2pstore data.csv

とするとPStore形式のdata.dbが得られます。
これで出力データが整ったので、CGIに取り掛かります。PStoreとならぶ必殺技、cgiでWebサーバとのインターフェイス、erbでHTML出力を担当させて、CGI本体(cgi.rb)は完成です。今回はアクセスのためのキーを入力するフォームとその出力結果を表示する部分を作りましたが、実際のHTML出力はcgiとは別のファイル、output.ehtmlに書いたので、拡張は混乱せずに行えるはずです。詳細はコード(続きにあります)を見て考えてみてください。
最後に、上で作った三つのファイル、data.dbとcgi.rbとoutput.ehtmlを適当な場所に配置して完成です。

今回は限られた時間でどこまでできるかチャレンジしましたが、コツさえつかめば簡単にこの程度のものはかけると思います。

csv2pstore.rb

#!/usr/local/bin/ruby -K s

require 'pstore'
DEBUG = true

src = ARGV.shift
dist = ""
if(ARGV.size > 0) then
    dist = SRGV.shift
else
    src =~ /([^\.]*)\.?/
    dist = $1 + "\.db"
end

db = PStore.new(dist)
db.transaction{
    ln = 0
    open(src).each_line{|line|
    
        if((ln += 1) > 1) then                #1行目は説明書きだったので無視
            line.chomp!                        #改行をとる
            values = line.split(',')        #CSV形式に
            if values.size > 0 then
                if DEBUG then p values end
                db[values.shift] = values    #先頭レコードをキーに、残りの値を配列としてぶち込む
            end
        end
    }
}

cgi.rb

#!/usr/local/bin/ruby
#written by fenrir

require "cgi"
require "pstore"
require "erb"

#File Setting
DB_FILE = "data.db"
VIEW_HTML = "output.ehtml"

#Query Setting
KEY = 'number'

def query2hash(query)
    temp = {}
    if query
        query.scan(/([^=]+)=([^&]+)&?/){|key, value|
            temp[key] = value
        }
    end
    return temp
end

#Main Routine
db = PStore.new DB_FILE
    
cgi = CGI.new("html4")
query = query2hash(ENV['QUERY_STRING'])

values = []
if query.key?(KEY) then
    db.transaction{
        if db.root?(key) then vlaues = db[query[KEY]] end
    }
end

print cgi.header({})
File.open(VIEW_HTML){|fh|
    ERB.new(fh.read.untaint).run(binding)
}

output.ehtml

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" />
</head>

<%
tytle =<<END
内容1
内容2

END
%>

<body>
<% if query[KEY] then %>
キー:<%= query[KEY] %>
    <% if values.size == 0 then %>
キーがあっていない可能性があります。もう一度入力してください。
    <% end %>
<dl>
    <% tytle.each_line{|tytle| %>
<dt><%= tytle %></dt><dd><%= values.shift %></dd>
    <% } %>
</dl>
<% else %>
<form action="http://<%= ENV['HTTP_HOST'] %><%= ENV['SCRIPT_NAME'] %>" method="get">
    キーを入力してください:<input name="<%= KEY %>" type="text" value="30" size="10">
    <input type="submit" value="確認">
</form>
<% end %>
</body>
</html>

17:35 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | この記事をdel.icio.usでブックマーク | トラックバック
このエントリーのトラックバックURL: http://fenrir.naruoka.org/mt/mt-tb.cgi/211
コメント
コメントする









名前、アドレスを登録しますか?
(次回以降コメント入力が楽になります)
  • 匿名でのコメントは受け付けておりません。
  • 名前(ハンドル名可)とメールアドレスは必ず入力してください。
  • メールアドレスを表示されたくないときはURLも必ず記入してください。
  • コメント欄でHTMLタグは使用できません。
  • コメント本文に日本語(全角文字)がある程度多く含まれている必要があります。
  • コメント欄内のURLと思われる文字列は自動的にリンクに変換されます。