2015年8月14日金曜日

[Python][CGI]MySQL からデータを読み込んでグラフを描く

#!/usr/bin/python
# -*- coding:utf-8 -*-
import MySQLdb
import tempfile
import os

# エラー発生時にレポートを表示
import cgitb
cgitb.enable()

html = """
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8"/>
<html>
<head>
<title>MySQL & Gnuplot</title>
</head>
<body>
data<br/>
%s
<img src="%s"/>
</body>
</html>
"""

####################################################################
# @brief グラフを描く
####################################################################
def drawGraph(dataFilename, pngfile, xmin, xmax, ymin, ymax):
 # plot データ作成
 (fd, pltFilename) = tempfile.mkstemp()

 # print "Plot tempfile name: %s" % (pltFilename)
 f = os.fdopen(fd, 'w')
 str = """
 set terminal png font "/usr/share/fonts/ipa-gothic/ipag.ttf,12"
 set output '%s'
 set title '各地の気温'
 set xlabel '場所'
 set ylabel '気温'
 set xrange [-1:3]
 set yrange [0:30]
 set boxwidth 0.5 relative
 set style fill solid 0.2
 set grid
 unset key
 plot '%s' using 2:xticlabels(1) with boxes
 """ % (pngfile, dataFilename)
 f.write(str)
 f.close()

 # gnuplot コマンド実行
 os.system("gnuplot %s" % pltFilename)

 # Temporary file 削除
 os.remove(pltFilename)

####################################################################
# @brief Main function
####################################################################
# DB に接続
db = MySQLdb.connect(user="username", passwd="password", db="dbname", charset="utf8")

# SELECT
q = "SELECT `area`, `temperature` FROM `temperature`;"
db.query(q)
result = db.store_result()

# データ表示 & データ格納
num = result.num_rows()
(fd, dataFilename) = tempfile.mkstemp()
f = os.fdopen(fd, 'w')
#print "filename: %s" % filename
data = """
<table border="1">
"""

for row in result.fetch_row(num):
 str = "<tr><td>%s</td><td>%.2f</td></tr>" % (row[0], row[1])
 data = data + str
 str = "%s\t%.2f\n" % (row[0], row[1])
 f.write(str)

data = data + "</table>"
f.close()

# グラフ作成
pngfile = "test03.png"
drawGraph(dataFilename, pngfile, -1, 3, 0, 30)

# Temporary file 削除
os.remove(dataFilename)

print html % (data, "test03.png")
これを実行しても SELinux が書き込みを禁止するので test03.png を cgi-bin 以下に生成することができない。
今は SELinux を一時停止して実験する。
# setenforce 0
この cgi ファイルのある場所に test03.png が作成されるが、cgi 実行権限のあるディレクトリ (cgi-bin) はすべて実行ファイルと解釈されるので画像が表示できない。
そこで httpd.conf の cgi ディレクトリ設定に AddHandler image/png .png を追加する。
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
AddHandler image/png .png
</Directory>
SELinux を有効のままでファイル書き込みを許可するにはスクリプトを実行するディレクトリの Type を httpd_sys_rw_content_t に変更する。
# ls -Z
drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_script_exec_t:s0 python
# chcon -t httpd_sys_script_rw_t python/
# ls -Z
drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_rw_content_t:s0 python

0 件のコメント:

コメントを投稿