# -*- coding:cp932 -*- # ウェブ調査票のようなものを作るための基本CGIスクリプト # 2010.2.16 / 2010.3.3 Yamamoto.T # # このスクリプトに対応したフォームの作成仕様: #
要素のmethodはどちらでもよいが、普通はPOST # actionは、このスクリプトをインポートするcgiスクリプトに。cgiの名前は何でもよい # # hidden要素として、id, quetions, *_title, mode, after を入れる。 # # id は、アンケートを区別するためのID。英数字で適当に。 # これにあわせて form_config の内容も適宜編集すること。 # # questionsは、回答として回収する要素名をすべて | でつなげて表記しておく。 # 例:q1|q2|q3 # # *_titleは、上のすべての回答要素の略名を設定するのに使う。 # 例:q1_title = 名前 # q2_title = 職名 ... # # modeは、preview と決め打ち。 # # afterは、入力完了後に表示させるページ。相対or絶対URL # # 実際の入力要素として、上のquestionsの各要素名を使って任意のタイプのフォームを書く。 # textタイプ、checkboxタイプ、radioタイプ、textareaタイプ、等々 # # 調査結果のcsvをExcelで開く人って多いので、今回はShiftJISバージョン # import sys import cgi # データ格納場所。絶対or相対パス store_path = "../data" # CGIからのパラメータ取得 f_store = cgi.FieldStorage() def _fm(key): return f_store.getfirst(key, '') form_id = _fm('id') # 稼動中のアンケートにあわせて適宜修正のこと # 'アンケートID': 'パスワード' # パスワードのハッシュ化をしようと思ったが、スクリプト見られる時点で # データファイルに接触されているのと同然だし、それ以上抵抗しないことにした。 # そのかわり、このスクリプトはインポート経由でのみ実行して、Webから直接アクセスさせない。 password = { 'test': 'password', 'test1': 'password', 'test2': 'password', }.get(form_id, 'defaultpassword') def header_and_title(title): return "Content-Type: text/html" + "\x0d\x0a\x0d\x0a" + """\ %s """ % title # エラー表示(具体的なメッセージを出さないのは手抜き…) def print_error(): print header_and_title('ERROR') + "ERROR!" # 入力内容テスト表示(mode=previewのかわりにmode=testにしてみると、ここに) def test_form(): print header_and_title('TEST') #cgi.print_environ_usage() #cgi.print_environ() for i in f_store.keys(): print "
%s
%s
" % (i, _fm(i)) # 入力内容確認画面 def form_preview(): print header_and_title('入力確認') print """\

この入力でよいですか?OKなら確定ボタンを押してください。
修正が必要なら、ブラウザの[戻る]ボタンなどで前画面に戻ってください。

""" % form_id qs = _fm('questions').split("|") after = _fm('after') print "" for q in qs: print "" % _fm('%s_title' % q) print "" % cgi.escape(_fm(q), True) print "
%s %s
" for q in qs: print "" % (q, cgi.escape(_fm(q), True)) print "" % _fm('questions') print "" % after print """\
""" # 入力確定 def store_data(): from datetime import datetime t = [datetime.now().strftime('%Y/%m/%d %H:%M:%S')] for q in _fm('questions').split("|"): t.append('"%s"' % cgi.escape(_fm(q), True).replace("\n", " ").replace("\r", " ")) o = open("%s/%s.csv" % (store_path, form_id), "a") o.write(",".join(t) + "\n") o.close() print "Location: %s\n" % _fm('after') # 回答データのダウンロード def download_data(): if (password == _fm('pass')): # データストアから結果の蓄積を読んで、そのままクライアントに渡す print "Content-Type: application/octet-stream" print "Content-Disposition: attachment filename=data_%s.csv" % form_id print for line in open("%s/%s.csv" % (store_path, form_id)): sys.stdout.write(line) else: # パスワード未入力、または不一致 print header_and_title('認証') print """\
PASSWORD:
""" % form_id {'test': test_form, 'preview': form_preview, 'confirm': store_data, 'download': download_data, }.get(_fm('mode'), print_error)()