SSブログ

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

WS000339.png

これまで、CGI内部で生成した文字列をデータベースに登録していく仕掛けを作ってきました。 今回は、HTML文書の "FORM" から文字列を入力して登録していく、掲示板みたいなものを作成してみました。

FORM の構成

HTML文書には、"TEXTAREA" を持った "FORM" が一つ埋め込んであります。 "Submit" ボタンを押すと、 CGI に "FORM" の情報が送信されるという仕組みになっています。 今回、送信に使用したのは、 "GET" という手法です。 これは、情報を URL に埋め込んで送信します。

<?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_world3.html,v 1.1 2009/03/01 07:26:41 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 3</title>
</head>
<body>
<h1>VISITOR WORLD 3</h1>
<form action="./visitor_world3.cgi" method="get">
<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>

CGI の悩み

"FORM" からは、URLの一部として "TEXTAREA" の情報が送られてきます。 この情報自身は、URLの流儀に従って、エンコードされているので、Pythonでは、 cgi.parse_qs というメソッドを使って簡単に文字列として取り出すことができます。 問題は、この文字列をどうやってデータベースに格納するかです。

通常、データベースには、文字列を格納することができます。 文字列を格納するときには、しかるべきライブラリによって、適切なエンコードが行われます。 ところが、さくらのレンタルサーバ・ライトプランでは、 SQLite をコマンドラインで使わざるをえません。 そのため、エンコード部分も自分で考えなくてはなりません。

そこで、Pythonの標準ライブラリを探し回って、二つほど解決策を考えました。

  • urllib.quote / urllib.unquote メソッドを使う

    このメソッドは、特殊文字を含んでいた場合に % を使った十六進表記で置き換えます。 良く URL の表記に使われている方法です。

    >>> urllib.quote("<p>\nHELLO\n</p>")
    '%3Cp%3E%0AHELLO%0A%3C/p%3E'
    
  • base64.b64encode / base64.b64decode メソッドを使う

    base64というのは、バイナリのデータを64種類の文字で置き換えるエンコード方法です。 良く、ファイルをメールに添付するときに使われます。

    >>> base64.b64encode("<p>\nHELLO\n</p>")
    'PHA+CkhFTExPCjwvcD4='
    

これらを見比べた結果、あとから人間が見たときによりわかりやすいと思われる、 "urllib.quote" を使うことにしました。

CGIの出来上がり

”FORM" 情報を受け取って、データベースに登録し、データベースの内容を表示する CGI に仕立てました。 使用したデータベースファイルは、前回の "VISITOR WORLD 2" で作成した "visitor.sqlite" をそのまま利用しました。

#!/usr/local/bin/python
# $Id: visitor_world3.cgi,v 1.1 2009/03/01 07:26:41 noritan Exp $

import os
import sys
import cgi
import urllib
import time

# Show error as a page description.
sys.stderr = sys.stdout

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

# Get and parse a query string
query_string_key = 'QUERY_STRING'
if query_string_key in os.environ:
    query = cgi.parse_qs(os.environ[query_string_key])
else:
    query = {}

# Get Current time
now = time.time()

# Get and escape a MESSAGE
message_key = 'message'
if message_key in query:
    message = urllib.quote(cgi.escape(query[message_key][0]))
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 3</title>
</head>
<body>
<h1>VISITOR WORLD 3</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 3
"FORM"入力ページは、ここにありますので、お試しください。 いちおう、"XHTML 1.1"認証済みです。

参考文献

Python Cookbook (Cookbook)

Python Cookbook (Cookbook)

  • 作者:
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2005/05/05
  • メディア: ペーパーバック
Python クックブック 第2版

Python クックブック 第2版

  • 作者: Alex Martelli
  • 出版社/メーカー: オライリー・ジャパン
  • 発売日: 2007/06/26
  • メディア: 大型本

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

nice! 0

コメント 0

コメントを書く

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

トラックバック 1

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