Python(Webアプリの1行チャット)
PythonでのWebアプリについては、 Python(webアプリ) を確認してから、今回の投稿を見てください。
PythonでWebアプリのプログラムを行う場合、print()を使って、Content-Typeを出力していましたが、ここで、出力する内容がHTMLであることをヘッダ情報として指定していました。
なので、HTMLのformやinput要素などのHTMLフォーム部品について確認しておきます。
要素
---------------------------
<input type = "text">
----- -------
属性 値
<html input要素のtype属性の主要な値>
・text 一行テキストボックス
・hidden 隠しフィールド(画面に表示されない)
・submit 送信ボタン
・checkbox チェックボックス
os.path.exists(FILE_LOG)で任意のパスにファイルがあるかどうかを確認。
htmlモジュールのescape()関数で、メッセージに含まれるHTMLの特殊記号「&」を「&」に、「>」を「>」に変換して、HTMLとして保存するようにする。
with open(FILE_LOG,"a+",encoding="utf-8") as f:
ファイルを"a+"追記モードで開き、write()メソッドでファイルの末尾に書き込む。
cgi.FieldStorage()でフォームのデータを取得。
<html lang="ja">
<head>
<meta charset="utf-8">
<title>htmlTest</title>
</head>
<form>
<input type="text" name="body" value="">
<input type="hidden" name="mode" value="read">
<input type="submit" value="発言">
</form>
</html>
HTMLでform要素を記述すると、その中に書いたinput要素の属性と値がフォームの送信対象になります。要素
---------------------------
<input type = "text">
----- -------
属性 値
<html input要素のtype属性の主要な値>
・text 一行テキストボックス
・hidden 隠しフィールド(画面に表示されない)
・submit 送信ボタン
・checkbox チェックボックス
フォームの値を受け取って足し算をするWebアプリ
#!/usr/bin/env python3
# 足し算を行うプログラム
import cgi
# ヘッダの出力
print("Content-Type: text/html; charset=utf-8")
print("")
# 送信されたフォームデータを取得する
form = cgi.FieldStorage()
# フォームにv1とv2のデータが含まれるか?
if(not "v1" in form) or (not "v2" in form):
# 含まれないのでフォームを表示
print("""
<form>
<input type="text" name="v1"> +
<input type="text" name="v2">
<input type="submit" value="計算">
</form>
""")
else:
# フォームの値を取得して計算結果を表示
v1=form.getvalue("v1","0")
v2=form.getvalue("v2","0")
try:
ans=int(v1)+int(v2)
except:
ans=0
print("<h1>",ans,"</h1>")
in演算子で任意の値がフォームデータに含まれているかどうか確認。getvalue()メソッドでフォームの値を取り出して計算。
チャットアプリ
#!/usr/bin/env python3
import cgi
import cgitb
import os.path
import html
# ブラウザでのデバッグを有効にする
cgitb.enable()
# 全体の設定
FILE_LOG="chat-log.txt"
# HTMLを画面に出力する
def print_html(body):
# ヘッダを出力
print("Content-Type: text/html; charset=utf-8")
print("")
# HTMLを出力
print("""
<html><head><meta charset="utf-8">
<title>チャット</title></head><body>
<h1>チャット</h1>
<div><form>
名前:<input type="text" name="name" size="8">
本文:<input type="text" name="body" size="20">
<input type="submit" value="発言">
<input type="hidden" name="mode" value="write">
</form></dir><hr>
{0}
</body></html>
""".format(body))
# 画面に書き込みログを表示する
def mode_read(form):
# ログを読み取る
log=""
if os.path.exists(FILE_LOG):
with open(FILE_LOG,"r",encoding="utf-8") as f:
log=f.read()
print_html(log)
# 任意のURLにジャンプする
def jump(url):
# ヘッダを出力
print("Status: 301 Moved Permanently") # Python簡易Webサーバでは省略不可
print("Location:" + url)
print("")
# HTMLを出力(ヘッダがうまく動かなかった時の対策)
print("<html><head>")
print('<meta http-equiv="refresh" content="0;'+ url + '">')
print("</head><body>")
print('<a href="'+url+'">jump</a></body></html>')
# メッセージの書き込み
def mode_write(form):
# パラメータを取得
name = form.getvalue("name","no name")
body = form.getvalue("body","")
# HTMLに変換
name = html.escape(name) # HTMLの特殊文字を変換
body = html.escape(body)
# ファイルに保存("a+"で追記モード)
with open(FILE_LOG,"a+",encoding="utf-8") as f:
f.write("<p>{0}: {1}</p><hr>\n".format(name,body))
# 書き込み後にリダイレクトする
jump("chat.py")
# メイン処理
def main():
# フォームの値を取得
form = cgi.FieldStorage()
# modeパラメータを取得
mode = form.getvalue("mode","read")
# modeの値によって処理を変更
if mode == "read":
mode_read(form)
elif mode == "write":
mode_write(form)
else:
mode_read(form)
# システム変数でimportモジュールでないか確認
if __name__=="__main__":
main()
cgitb.enable()でプログラムのエラーをWebブラウザに出力。os.path.exists(FILE_LOG)で任意のパスにファイルがあるかどうかを確認。
htmlモジュールのescape()関数で、メッセージに含まれるHTMLの特殊記号「&」を「&」に、「>」を「>」に変換して、HTMLとして保存するようにする。
with open(FILE_LOG,"a+",encoding="utf-8") as f:
ファイルを"a+"追記モードで開き、write()メソッドでファイルの末尾に書き込む。
cgi.FieldStorage()でフォームのデータを取得。
HTMLで任意のURLにジャンプする場合のヘッダデータ
Status: 301 Moved Permanently
Location: url (改行)
(改行)
Webブラウザ側で自動的に任意のページにジャンプする記述
<meta
http-equiv = "refresh"
content = "0; url" >