SSブログ

Python CGI で 掲示板みたいなものを作る~FieldStorage編~ [プログラム三昧]このエントリーを含むはてなブックマーク#

WS000257.png

前回の記事Python CGI で 掲示板みたいなものを作る~POST編~では、 "cgi.parse_qs()" を使って query を取り出す方法を使いました。 今回は、こんどはPOSTを受ける方法。で紹介されていた "cgi.FieldStorage()" を使用してみます。 もしかして、こっちが、本流なのかな?

FORMの構成

HTML文書は、タイトルと呼び出すCGIが変わっただけです。 もう、説明はいらないよね。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<!-- $Id: visitor_world5.html,v 1.1 2009/06/06 05:07:43 noritan Exp $ -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" >
<head profile="http://www.w3.org/2005/10/profile">
<title>VISITOR WORLD 5</title>
</head>
<body>
<h1>VISITOR WORLD 5</h1>
<form action="./visitor_world5.cgi" method="post">
<div>
<textarea name="message" rows="4" cols="40"></textarea>
</div>
<p>
<input type="submit" value="Submit" />
<input type="reset" value="Clear" />
</p>
</form>
</body>
</html>

query データベースの作り方と使い方

前回は query のデータベースを "cgi.parse_qs()" メソッドで作成していましたが、今回は、 "cgi.FieldStorage()" オブジェクトとして生成します。

  • BEFORE
    # Get a POST data.
    content_length = int(os.environ['CONTENT_LENGTH'])
    query = cgi.parse_qs(sys.stdin.read(content_length))
    
  • AFTER
    # Get a POST data.
    form = cgi.FieldStorage()
    

今まで苦労してたのが、ウソみたいだ。 出来上がったデータベースは、 "cgi.parse_qs" で作成した方は、 Python のデータベースオブジェクトそのものでしたが、 "cgi.FieldStorage()" の方は再帰的な木構造を持っています。 そのため、目的の要素を取り出す方法も異なっています。

  • BEFORE
    # Get and escape a MESSAGE
    message_key = 'message'
    if message_key in query:
        message = urllib.quote(cgi.escape(query[message_key][0]))
    else:
        message = ""
    
  • AFTER
    # Get and escape a MESSAGE
    message_key = 'message'
    if message_key in form:
        message = urllib.quote(cgi.escape(str(form.getvalue(message_key))))
    else:
        message = ""
    

"FieldStorage" から要素を取り出すには、色々なメソッドがあります。 今回は、手ごろなところで、 "FieldStorage.getvalue()" を使いました。

先に書いたように、 FieldStorage クラスは木構造を持っています。 したがって、 "FieldStorage.getvalue()" メソッドで取り出した値が文字列であるという保証はどこにもありません。 その正体不明の要素を確実に文字列にするため、 "str()" 関数を使っています。 これで、確実に何らかの文字列が得られます。

CGIの出来上がり

という訳で、できあがりました。

#!/usr/local/bin/python
# $Id: visitor_world5.cgi,v 1.1 2009/06/06 05:07:43 noritan Exp $

import os
import sys
import cgi
import urllib
import time
import cgitb

# Show error as a page description.
sys.stderr = sys.stdout
cgitb.enable()

# Database releated information
db_file = "visitor.sqlite"
table_name = "visitor"
command = "/usr/local/bin/sqlite3 %s" % (db_file)

# Get a POST data.
form = cgi.FieldStorage()

# Get Current time
now = time.time()

# Get and escape a MESSAGE
message_key = 'message'
if message_key in form:
    message = urllib.quote(cgi.escape(str(form.getvalue(message_key))))
else:
    message = ""

# Compose a SQL
sql = "SELECT time, description FROM %(table)s ORDER BY time DESC;"
if len(message) > 0:
    sql = \
      "INSERT INTO %(table)s VALUES (%(now)f, \"%(message)s\");\n" \
      + sql

# Show HTML header
print """Content-type: text/html

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head profile="http://www.w3.org/2005/10/profile">
<link rel="icon" href="/favicon.png" type="image/png" />
<title>VISITOR WORLD 5</title>
</head>
<body>
<h1>VISITOR WORLD 5</h1>
"""

# Access to the DATABSE
(pipe_out, pipe_in) = os.popen2(command)
pipe_out.write(
  sql % {"table":table_name, "now":now, "message":message}
)
pipe_out.close()

# Show a list of visitor record
print """<dl>
"""

# Make a list of messages
try:
    for line in pipe_in:
        field = line.split("|")
        asctime = time.strftime(
          "%Y-%m-%d (%A) %H:%M:%S",
          time.localtime(float(field[0]))
        )
        message = urllib.unquote(field[1])
        print "<dt>%s</dt><dd>%s</dd>\n" % (asctime, message)
finally:
    pipe_in.close()


# Show footer
print """
</dl>
</body>
</html>
"""

参考サイト

VISITOR WORLD 5
"FORM"入力ページは、ここにありますので、お試しください。
Python v2.6.2 documentation
python.org にあるオンラインドキュメントです。 現在、私が使っているサーバにインストールされている python は、 version 2.4.5 なのですが、ここには、原稿執筆時点で version 2.6.2 が置いてあります。 ちょっと、注意しながら使わなくては。
21.2. cgi — Common Gateway Interface support.
cgi パッケージ関連のマニュアルです。 FieldStorage クラスの解説は、これだけなのかな?

参考文献

Learning Python 3e (Learning)

Learning Python 3e (Learning)

  • 作者: M Lutz
  • 出版社/メーカー: Pragma
  • 発売日: 2007/11/06
  • メディア: ペーパーバック
初めてのPython 第3版

初めてのPython 第3版

  • 作者: Mark Lutz
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2009/02/26
  • メディア: 大型本

nice!(0)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました