Python(Webアプリの1行チャット)

PythonでのWebアプリについては、 Python(webアプリ) を確認してから、今回の投稿を見てください。 PythonでWebアプリのプログラムを行う場合、print()を使って、Content-Typeを出力していましたが、ここで、出力する内容がHTMLであることをヘッダ情報として指定していました。 なので、HTMLのformやinput要素などのHTMLフォーム部品について確認しておきます。
<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" >

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Python

前の記事

Python(webアプリ)
Python

次の記事

Python(会員制Webサイト)