著者:松浦 智之
システム開発手法「ユニケージ」では、データ保存用に「ファイル」を使い、ユニケージ専用コマンド群「usp Tukubai」と「シェルスクリプト」で業務システムを開発します。usp Tukubaiは有償ソフトですが、無償のオープンソース版「Open usp Tukubai」もあります。このOpen usp Tukubaiを使って、ユニケージ開発を無料で始めてみましょう。
シェルスクリプトマガジン Vol.79は以下のリンク先でご購入できます。![]()
![]()
図6 Apache HTTP Serverの郵便番号・住所検索システム用設定ファイル(/etc/apache2/sites-available/zip2addr.conf)
<IfModule alias_module>
Alias /zip2addr /home/ユーザー名/ZIP2ADDR/public_html
<Directory /home/ユーザー名/ZIP2ADDR/public_html>
AddHandler cgi-script .cgi
Options all
Require all granted
</Directory>
</IfModule>
図10 MK_ZIPTBL.SHのソースコード
#!/bin/sh -u
(略)
homd=$(d=${0%/*}/; [ "_$d" = "_$0/" ] && d='./'; cd "$d.."; pwd)
datd=$homd/DATA
shld=$homd/SHELL
webd=$homd/public_html
url_ken=https://www.post.japanpost.jp/zipcode/dl/oogaki/zip/ken_all.zip
url_jig=https://www.post.japanpost.jp/zipcode/dl/jigyosyo/zip/jigyosyo.zip
export LC_ALL=C
(略)
nocmds=''
type wget >/dev/null 2>&1 || { nocmds="$nocmds,wget" ; }
type gunzip >/dev/null 2>&1 || { nocmds="$nocmds,gunzip"; }
type iconv >/dev/null 2>&1 || { nocmds="$nocmds,iconv" ; }
if [ -n "$nocmds" ]; then
echo "${0##*/}: ${nocmds#,} not found. Install them in advance." 1>&2
exit 1
fi
(略)
wget -q -O - "$url_ken" |
gunzip |
tr -d '\r' |
iconv -c -f Shift_JIS -t UTF-8 |
tr -d '"' |
awk -F , '{print $3,$7,$8,$9}' > $datd/ziptbl_ken.txt
if [ ! -s $datd/ziptbl_ken.txt ]; then
echo "${0##*/}: Failed to make zip_ken.txt" 1>&2; exit 1
fi
(略)
wget -q -O - "$url_jig" |
gunzip |
tr -d '\r' |
iconv -c -f Shift_JIS -t UTF-8 |
tr -d '"' |
awk -F , '{print $8,$4,$5,$6 $7}' > $datd/ziptbl_jig.txt
if [ ! -s $datd/ziptbl_jig.txt ]; then
echo "${0##*/}: Failed to make zip_ken.txt" 1>&2; exit 1
fi
(略)
exit 0
図12 ZIP2ADDR.AJAX.cgiのコード
#!/bin/sh -u
(略)
homd=$(d=${0%/*}/; [ "_$d" = "_$0/" ] && d='./'; cd "$d.."; pwd)
datd=$homd/DATA
shld=$homd/SHELL
webd=$homd/public_html
export LC_ALL=C
(略)
exit_trap() {
set -- ${1:-} $? # $? is set as $1 if no argument given
trap '' EXIT HUP INT QUIT PIPE ALRM TERM
[ -d "${tmpd:-}" ] && rm -rf "$tmpd"
trap - EXIT HUP INT QUIT PIPE ALRM TERM
exit $1
}
error500_exit() {
echo 'Status: 500 Internal Server Error'
echo 'Content-Type: text/plain'
echo
echo '500 Internal Server Error'
echo "($@)"
exit 1
}
error400_exit() {
echo 'Status: 400 Bad Request'
echo 'Content-Type: text/plain'
echo
echo '400 Bad Request'
echo "($@)"
exit 1
}
(略)
trap 'exit_trap' EXIT HUP INT QUIT PIPE ALRM TERM
tmpd=$(mktemp -d -t "_${0##*/}.$$.XXXXXXXXXXX")
[ -d "$tmpd" ] || error500_exit 'Failed to mktemp'
(略)
printf '%s\n' "${QUERY_STRING:-}" |
cgi-name > $tmpd/cgivars
zip=$(nameread zipcode $tmpd/cgivars)
printf '%s\n' "$zip" | grep -qE '^[0-9]{7}$' || error400_exit 'Invalid zipcode'
(略)
echo $homd/DATA/ziptbl* | grep -qF '*' && error500_exit 'No table files exist'
cat $homd/DATA/ziptbl* |
awk '$1=="'"$zip"'"{print "pref",$2;
print "city",$3;
print "town",$4;}' > $tmpd/address123
[ -s $tmpd/address123 ] || error400_exit 'No address found'
(略)
echo 'Content-Type: text/html; charset=utf-8'
echo 'Cache-Control: private, no-store, no-cache, must-revalidate'
echo 'Pragma: no-cache'
echo
formhame $webd/ZIP2ADDR.html $tmpd/address123 |
sed -n '/BEGIN ADDRESS123/,/END ADDRESS123/p'
(略)
[ -d "${tmpd:-}" ] && rm -rf "$tmpd"
exit 0
図13 ZIP2ADDR.htmlのコード
<!DOCTYPE html>
(略)
<script type="text/javascript" src="ZIP2ADDR.js"></script>
(略)
</head>
<body>
<h1>郵便番号→住所検索 デモ</h1>
<form action="#dummy">
<table border="0" id="addressform">
<tr>
<td>
<dl>
<dt>郵便番号</dt>
<dd><input id="zipcode1" type="text" name="zipcode1" value="" size="3" maxlength="3" />-<input id="zipcode2" type="text" name="zipcode2" value="" size="4" maxlength="4" /></dd>
<dd><input id="run" type="button" name="run" value="検索実行!" onclick="zip2addr();"></dd>
</dl>
</td>
</tr>
<tr>
<td>
<dl id="adress123">
<!-- BEGIN ADDRESS123-->
<dt>住所(都道府県名)</dt>
<dd>
<select id="pref" name="pref">
<option value="(未選択)">(未選択)</option>
(略)
<option value="沖縄県" >沖縄県</option>
</select>
</dd>
<dt>住所(市区町村名)</dt><dd><input id="city" type="text" size="60" name="city" value="" /></dd>
<dt>住所(町名以降)</dt><dd><input id="town" type="text" size="60" name="town" value="" /></dd>
<!-- END ADDRESS123-->
</dl>
</td>
</tr>
</table>
</form>
</body>
</html>
図14 ZIP2ADDR.jsのコード
(略)
function zip2addr() {
var url;
var zipcode;
var xhr;
(略)
if (! document.getElementById('zipcode1').value.match(/^([0-9]{3})$/)) {
alert('郵便番号(前の3桁)が正しくありません');
return;
}
zipcode = RegExp.$1;
if (! document.getElementById('zipcode2').value.match(/^([0-9]{4})$/)) {
alert('郵便番号(後の4桁)が正しくありません');
return;
}
zipcode += RegExp.$1;
(略)
xhr = createXMLHttpRequest();
if (xhr) {
url = 'ZIP2ADDR.AJAX.cgi?zipcode='+zipcode;
url += '&dummy='+parseInt((new Date)/1);
xhr.open('GET', url, true);
xhr.onreadystatechange = function(){zip2addr_callback(xhr)};
xhr.send(null);
}
(略)
return;
}
(略)
function zip2addr_callback(xhr) {
var e;
(略)
if (xhr.readyState != 4) {return;}
if (xhr.status == 0 ) {return;}
if (xhr.status == 400) {
alert('郵便番号が正しくありません');
return;
}
else if (xhr.status != 200) {
alert('アクセスエラー(' + xhr.status + ')');
return;
}
(略)
e = document.getElementById('adress123');
if (!e) {alert('エラー: 住所欄が存在しない!'); return;}
e.innerHTML = xhr.responseText;
(略)
return;
}